📄 rtlanal.c
字号:
return XSTR (x, 0) == XSTR (y, 0); /* Compare the elements. If any pair of corresponding elements fail to match, return 0 for the whole things. */ fmt = GET_RTX_FORMAT (code); for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) { switch (fmt[i]) { case 'i': if (XINT (x, i) != XINT (y, i)) return 0; break; case 'E': /* Two vectors must have the same length. */ if (XVECLEN (x, i) != XVECLEN (y, i)) return 0; /* And the corresponding elements must match. */ for (j = 0; j < XVECLEN (x, i); j++) if (rtx_equal_p (XVECEXP (x, i, j), XVECEXP (y, i, j)) == 0) return 0; break; case 'e': if (rtx_equal_p (XEXP (x, i), XEXP (y, i)) == 0) return 0; break; case 's': if (strcmp (XSTR (x, i), XSTR (y, i))) return 0; break; case 'u': /* These are just backpointers, so they don't matter. */ break; case '0': break; /* It is believed that rtx's at this level will never contain anything but integers and other rtx's, except for within LABEL_REFs and SYMBOL_REFs. */ default: abort (); } } return 1;}/* Call FUN on each register or MEM that is stored into or clobbered by X. (X would be the pattern of an insn). FUN receives two arguments: the REG, MEM, CC0 or PC being stored in or clobbered, the SET or CLOBBER rtx that does the store. */ voidnote_stores (x, fun) register rtx x; void (*fun) ();{ if ((GET_CODE (x) == SET || GET_CODE (x) == CLOBBER)) { register rtx dest = SET_DEST (x); while (GET_CODE (dest) == SUBREG || GET_CODE (dest) == ZERO_EXTRACT || GET_CODE (dest) == SIGN_EXTRACT || GET_CODE (dest) == STRICT_LOW_PART) dest = XEXP (dest, 0); (*fun) (dest, x); } else if (GET_CODE (x) == PARALLEL) { register int i; for (i = XVECLEN (x, 0) - 1; i >= 0; i--) { register rtx y = XVECEXP (x, 0, i); if (GET_CODE (y) == SET || GET_CODE (y) == CLOBBER) { register rtx dest = SET_DEST (y); while (GET_CODE (dest) == SUBREG || GET_CODE (dest) == ZERO_EXTRACT || GET_CODE (dest) == SIGN_EXTRACT || GET_CODE (dest) == STRICT_LOW_PART) dest = XEXP (dest, 0); (*fun) (dest, XVECEXP (x, 0, i)); } } }}/* Return nonzero if register REG's old contents don't survive after INSN. This can be because REG dies in INSN or because INSN entirely sets REG. "Entirely set" means set directly and not through a SUBREG, ZERO_EXTRACT or SIGN_EXTRACT, so no trace of the old contents remains. REG may be a hard or pseudo reg. Renumbering is not taken into account, but for this use that makes no difference, since regs don't overlap during their lifetimes. Therefore, this function may be used at any time after deaths have been computed (in flow.c). */intdead_or_set_p (insn, reg) rtx insn; rtx reg;{ register rtx link; register int regno = REGNO (reg); for (link = REG_NOTES (insn); link; link = XEXP (link, 1)) if ((REG_NOTE_KIND (link) == REG_DEAD || REG_NOTE_KIND (link) == REG_INC) && REGNO (XEXP (link, 0)) == regno) return 1; if (GET_CODE (PATTERN (insn)) == SET) return (GET_CODE (SET_DEST (PATTERN (insn))) == REG && REGNO (SET_DEST (PATTERN (insn))) == regno); else if (GET_CODE (PATTERN (insn)) == PARALLEL) { register int i; for (i = XVECLEN (PATTERN (insn), 0) - 1; i >= 0; i--) { if (GET_CODE (XVECEXP (PATTERN (insn), 0, i)) == SET && GET_CODE (SET_DEST (XVECEXP (PATTERN (insn), 0, i))) == REG && REGNO (SET_DEST (XVECEXP (PATTERN (insn), 0, i))) == regno) return 1; } } return 0;}/* Like dead_or_set_p, but return 1 if even a part of the register's value is set. */intdead_or_partially_set_p (insn, reg) rtx insn; rtx reg;{ register rtx link; register int regno = REGNO (reg); for (link = REG_NOTES (insn); link; link = XEXP (link, 1)) if ((REG_NOTE_KIND (link) == REG_DEAD || REG_NOTE_KIND (link) == REG_INC) && REGNO (XEXP (link, 0)) == regno) return 1; if (GET_CODE (PATTERN (insn)) == SET) { rtx dest = SET_DEST (PATTERN (insn)); while (GET_CODE (dest) == SUBREG || GET_CODE (dest) == STRICT_LOW_PART || GET_CODE (dest) == ZERO_EXTRACT || GET_CODE (dest) == SIGN_EXTRACT) dest = SUBREG_REG (dest); return (GET_CODE (dest) == REG && REGNO (dest) == regno); } else if (GET_CODE (PATTERN (insn)) == PARALLEL) { register int i; for (i = XVECLEN (PATTERN (insn), 0) - 1; i >= 0; i--) { if (GET_CODE (XVECEXP (PATTERN (insn), 0, i)) == SET) { rtx dest = SET_DEST (XVECEXP (PATTERN (insn), 0, i)); while (GET_CODE (dest) == SUBREG || GET_CODE (dest) == STRICT_LOW_PART || GET_CODE (dest) == ZERO_EXTRACT || GET_CODE (dest) == SIGN_EXTRACT) dest = SUBREG_REG (dest); if (GET_CODE (dest) == REG && REGNO (dest) == regno) return 1; } } } return 0;}/* Return the reg-note of kind KIND in insn INSN, if there is one. If DATUM is nonzero, look for one whose datum is DATUM. */rtxfind_reg_note (insn, kind, datum) rtx insn; enum reg_note kind; rtx datum;{ register rtx link; for (link = REG_NOTES (insn); link; link = XEXP (link, 1)) if (REG_NOTE_KIND (link) == kind && (datum == 0 || datum == XEXP (link, 0))) return link; return 0;}/* Return the reg-note of kind KIND in insn INSN which applies to register number REGNO, if any. Return 0 if there is no such reg-note. */rtxfind_regno_note (insn, kind, regno) rtx insn; enum reg_note kind; int regno;{ register rtx link; for (link = REG_NOTES (insn); link; link = XEXP (link, 1)) if (REG_NOTE_KIND (link) == kind && REGNO (XEXP (link, 0)) == regno) return link; return 0;}/* Nonzero if FROM precedes TO with no intervening labels. */intno_labels_between (from, to) register rtx from, to;{ register rtx p = to; while (1) { p = PREV_INSN (p); if (p == 0) return 0; if (p == from) return 1; if (GET_CODE (p) == CODE_LABEL) return 0; }}/* Nonzero if X contains any volatile memory references or volatile ASM_OPERANDS expressions. */intvolatile_refs_p (x) rtx x;{ register RTX_CODE code; code = GET_CODE (x); switch (code) { case LABEL_REF: case SYMBOL_REF: case CONST_INT: case CONST: case CONST_DOUBLE: case CC0: case PC: case REG: case CLOBBER: case ASM_INPUT: case ADDR_VEC: case ADDR_DIFF_VEC: return 0; case CALL: return 1; case MEM: case ASM_OPERANDS: if (MEM_VOLATILE_P (x)) return 1; } /* Recursively scan the operands of this expression. */ { register char *fmt = GET_RTX_FORMAT (code); register int i; for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) { if (fmt[i] == 'e') { if (volatile_refs_p (XEXP (x, i))) return 1; } if (fmt[i] == 'E') { register int j; for (j = 0; j < XVECLEN (x, i); j++) if (volatile_refs_p (XVECEXP (x, i, j))) return 1; } } } return 0;}/* Return nonzero if evaluating rtx X might cause a trap. */intmay_trap_p (x) rtx x;{ int i; enum rtx_code code; char *fmt; if (x == 0) return 0; code = GET_CODE (x); switch (code) { /* Handle these cases fast. */ case CONST_INT: case CONST_DOUBLE: case SYMBOL_REF: case LABEL_REF: case CONST: case PC: case CC0: case REG: return 0; /* Memory ref can trap unless it's a static var or a stack slot. */ case MEM: return rtx_varies_p (XEXP (x, 0)); /* Division by a non-constant might trap. */ case DIV: case MOD: case UDIV: case UMOD: if (! CONSTANT_P (XEXP (x, 1)) && GET_CODE (XEXP (x, 1)) != CONST_DOUBLE) return 1; if (XEXP (x, 1) == const0_rtx) return 1; default: /* Any floating arithmetic may trap. */ if (GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT) return 1; } fmt = GET_RTX_FORMAT (code); for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) { if (fmt[i] == 'e') { if (may_trap_p (XEXP (x, i))) return 1; } else if (fmt[i] == 'E') { register int j; for (j = 0; j < XVECLEN (x, i); j++) if (may_trap_p (XVECEXP (x, i, j))) return 1; } } return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -