📄 rtlanal.c
字号:
if (GET_CODE (PATTERN (insn)) == SET) { rtx dest = SET_DEST (PATTERN (insn)); /* A value is totally replaced if it is the destination or the destination is a SUBREG of REGNO that does not change the number of words in it. */ if (GET_CODE (dest) == SUBREG && (((GET_MODE_SIZE (GET_MODE (dest)) + UNITS_PER_WORD - 1) / UNITS_PER_WORD) == ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (dest))) + UNITS_PER_WORD - 1) / UNITS_PER_WORD))) dest = SUBREG_REG (dest); if (GET_CODE (dest) != REG) return 0; regno = REGNO (dest); endregno = (regno >= FIRST_PSEUDO_REGISTER ? regno + 1 : regno + HARD_REGNO_NREGS (regno, GET_MODE (dest))); return (test_regno >= regno && test_regno < endregno); } else if (GET_CODE (PATTERN (insn)) == PARALLEL) { register int i; for (i = XVECLEN (PATTERN (insn), 0) - 1; i >= 0; i--) { rtx body = XVECEXP (PATTERN (insn), 0, i); if (GET_CODE (body) == SET || GET_CODE (body) == CLOBBER) { rtx dest = SET_DEST (body); if (GET_CODE (dest) == SUBREG && (((GET_MODE_SIZE (GET_MODE (dest)) + UNITS_PER_WORD - 1) / UNITS_PER_WORD) == ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (dest))) + UNITS_PER_WORD - 1) / UNITS_PER_WORD))) dest = SUBREG_REG (dest); if (GET_CODE (dest) != REG) continue; regno = REGNO (dest); endregno = (regno >= FIRST_PSEUDO_REGISTER ? regno + 1 : regno + HARD_REGNO_NREGS (regno, GET_MODE (dest))); if (test_regno >= regno && test_regno < endregno) 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 /* Verify that it is a register, so that scratch and MEM won't cause a problem here. */ && GET_CODE (XEXP (link, 0)) == REG && REGNO (XEXP (link, 0)) == regno) return link; return 0;}/* Remove register note NOTE from the REG_NOTES of INSN. */voidremove_note (insn, note) register rtx note; register rtx insn;{ register rtx link; if (REG_NOTES (insn) == note) { REG_NOTES (insn) = XEXP (note, 1); return; } for (link = REG_NOTES (insn); link; link = XEXP (link, 1)) if (XEXP (link, 1) == note) { XEXP (link, 1) = XEXP (note, 1); return; } abort ();}/* Nonzero if X contains any volatile memory references UNSPEC_VOLATILE operations 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 SCRATCH: case CLOBBER: case ASM_INPUT: case ADDR_VEC: case ADDR_DIFF_VEC: return 0; case CALL: case UNSPEC_VOLATILE: /* case TRAP_IF: This isn't clear yet. */ 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;}/* Similar to above, except that it also rejects register pre- and post- incrementing. */intside_effects_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 SCRATCH: case ASM_INPUT: case ADDR_VEC: case ADDR_DIFF_VEC: return 0; case CLOBBER: /* Reject CLOBBER with a non-VOID mode. These are made by combine.c when some combination can't be done. If we see one, don't think that we can simplify the expression. */ return (GET_MODE (x) != VOIDmode); case PRE_INC: case PRE_DEC: case POST_INC: case POST_DEC: case CALL: case UNSPEC_VOLATILE: /* case TRAP_IF: This isn't clear yet. */ 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 (side_effects_p (XEXP (x, i))) return 1; } if (fmt[i] == 'E') { register int j; for (j = 0; j < XVECLEN (x, i); j++) if (side_effects_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 quickly. */ case CONST_INT: case CONST_DOUBLE: case SYMBOL_REF: case LABEL_REF: case CONST: case PC: case CC0: case REG: case SCRATCH: return 0; /* Conditional trap can trap! */ case UNSPEC_VOLATILE: case TRAP_IF: return 1; /* Memory ref can trap unless it's a static var or a stack slot. */ case MEM: return rtx_addr_can_trap_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))) return 1; /* This was const0_rtx, but by not using that, we can link this file into other programs. */ if (GET_CODE (XEXP (x, 1)) == CONST_INT && INTVAL (XEXP (x, 1)) == 0) 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;}/* Return nonzero if X contains a comparison that is not either EQ or NE, i.e., an inequality. */intinequality_comparisons_p (x) rtx x;{ register char *fmt; register int len, i; register enum rtx_code code = GET_CODE (x); switch (code) { case REG: case SCRATCH: case PC: case CC0: case CONST_INT: case CONST_DOUBLE: case CONST: case LABEL_REF: case SYMBOL_REF: return 0; case LT: case LTU: case GT: case GTU: case LE: case LEU: case GE: case GEU: return 1; } len = GET_RTX_LENGTH (code); fmt = GET_RTX_FORMAT (code); for (i = 0; i < len; i++) { if (fmt[i] == 'e') { if (inequality_comparisons_p (XEXP (x, i))) return 1; } else if (fmt[i] == 'E') { register int j; for (j = XVECLEN (x, i) - 1; j >= 0; j--) if (inequality_comparisons_p (XVECEXP (x, i, j))) return 1; } } return 0;}/* Replace any occurrence of FROM in X with TO. Note that copying is not done so X must not be shared unless all copies are to be modified. */rtxreplace_rtx (x, from, to) rtx x, from, to;{ register int i, j; register char *fmt; if (x == from) return to; /* Allow this function to make replacements in EXPR_LISTs. */ if (x == 0) return 0; fmt = GET_RTX_FORMAT (GET_CODE (x)); for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--) { if (fmt[i] == 'e') XEXP (x, i) = replace_rtx (XEXP (x, i), from, to); else if (fmt[i] == 'E') for (j = XVECLEN (x, i) - 1; j >= 0; j--) XVECEXP (x, i, j) = replace_rtx (XVECEXP (x, i, j), from, to); } return x;} /* Throughout the rtx X, replace many registers according to REG_MAP. Return the replacement for X (which may be X with altered contents). REG_MAP[R] is the replacement for register R, or 0 for don't replace. NREGS is the length of REG_MAP; regs >= NREGS are not mapped. We only support REG_MAP entries of REG or SUBREG. Also, hard registers should not be mapped to pseudos or vice versa since validate_change is not called. If REPLACE_DEST is 1, replacements are also done in destinations; otherwise, only sources are replaced. */rtxreplace_regs (x, reg_map, nregs, replace_dest) rtx x; rtx *reg_map; int nregs; int replace_dest;{ register enum rtx_code code; register int i; register char *fmt; if (x == 0) return x; code = GET_CODE (x); switch (code) { case SCRATCH: case PC: case CC0: case CONST_INT: case CONST_DOUBLE: case CONST: case SYMBOL_REF: case LABEL_REF: return x; case REG: /* Verify that the register has an entry before trying to access it. */ if (REGNO (x) < nregs && reg_map[REGNO (x)] != 0) return reg_map[REGNO (x)]; return x; case SUBREG: /* Prevent making nested SUBREGs. */ if (GET_CODE (SUBREG_REG (x)) == REG && REGNO (SUBREG_REG (x)) < nregs && reg_map[REGNO (SUBREG_REG (x))] != 0 && GET_CODE (reg_map[REGNO (SUBREG_REG (x))]) == SUBREG) { rtx map_val = reg_map[REGNO (SUBREG_REG (x))]; rtx map_inner = SUBREG_REG (map_val); if (GET_MODE (x) == GET_MODE (map_inner)) return map_inner; else { /* We cannot call gen_rtx here since we may be linked with genattrtab.c. */ /* Let's try clobbering the incoming SUBREG and see if this is really safe. */ SUBREG_REG (x) = map_inner; SUBREG_WORD (x) += SUBREG_WORD (map_val); return x;#if 0 rtx new = rtx_alloc (SUBREG); PUT_MODE (new, GET_MODE (x)); SUBREG_REG (new) = map_inner; SUBREG_WORD (new) = SUBREG_WORD (x) + SUBREG_WORD (map_val);#endif } } break; case SET: if (replace_dest) SET_DEST (x) = replace_regs (SET_DEST (x), reg_map, nregs, 0); else if (GET_CODE (SET_DEST (x)) == MEM || GET_CODE (SET_DEST (x)) == STRICT_LOW_PART) /* Even if we are not to replace destinations, replace register if it is CONTAINED in destination (destination is memory or STRICT_LOW_PART). */ XEXP (SET_DEST (x), 0) = replace_regs (XEXP (SET_DEST (x), 0), reg_map, nregs, 0); else if (GET_CODE (SET_DEST (x)) == ZERO_EXTRACT) /* Similarly, for ZERO_EXTRACT we replace all operands. */ break; SET_SRC (x) = replace_regs (SET_SRC (x), reg_map, nregs, 0); return x; } fmt = GET_RTX_FORMAT (code); for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) { if (fmt[i] == 'e') XEXP (x, i) = replace_regs (XEXP (x, i), reg_map, nregs, replace_dest); if (fmt[i] == 'E') { register int j; for (j = 0; j < XVECLEN (x, i); j++) XVECEXP (x, i, j) = replace_regs (XVECEXP (x, i, j), reg_map, nregs, replace_dest); } } return x;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -