Mercurial > hg > CbC > CbC_gcc
diff gcc/jump.c @ 55:77e2b8dfacca gcc-4.4.5
update it from 4.4.3 to 4.5.0
author | ryoma <e075725@ie.u-ryukyu.ac.jp> |
---|---|
date | Fri, 12 Feb 2010 23:39:51 +0900 |
parents | a06113de4d67 |
children | b7f97abdc517 |
line wrap: on
line diff
--- a/gcc/jump.c Sun Feb 07 18:28:00 2010 +0900 +++ b/gcc/jump.c Fri Feb 12 23:39:51 2010 +0900 @@ -68,6 +68,7 @@ static void init_label_info (rtx); static void mark_all_labels (rtx); static void mark_jump_label_1 (rtx, rtx, bool, bool); +static void mark_jump_label_asm (rtx, rtx); static void redirect_exp_1 (rtx *, rtx, rtx, rtx); static int invert_exp_1 (rtx, rtx); static int returnjump_p_1 (rtx *, void *); @@ -113,6 +114,8 @@ if (BARRIER_P (insn)) { prev = prev_nonnote_insn (insn); + if (!prev) + continue; if (BARRIER_P (prev)) delete_insn (insn); else if (prev != PREV_INSN (insn)) @@ -132,7 +135,7 @@ NULL, /* sub */ NULL, /* next */ 0, /* static_pass_number */ - 0, /* tv_id */ + TV_NONE, /* tv_id */ 0, /* properties_required */ 0, /* properties_provided */ 0, /* properties_destroyed */ @@ -230,7 +233,7 @@ && (rtx_equal_p (label_dest, XEXP (pc_src, 1)) || rtx_equal_p (label_dest, XEXP (pc_src, 2)))))) - + { /* The CODE_LABEL referred to in the note must be the CODE_LABEL in the LABEL_REF of the "set". We can @@ -389,7 +392,7 @@ /* Test for an integer condition, or a floating-point comparison in which NaNs can be ignored. */ - if (GET_CODE (arg0) == CONST_INT + if (CONST_INT_P (arg0) || (GET_MODE (arg0) != VOIDmode && GET_MODE_CLASS (mode) != MODE_CC && !HONOR_NANS (mode))) @@ -869,10 +872,25 @@ { rtx x = *loc; - return x && (GET_CODE (x) == RETURN - || (GET_CODE (x) == SET && SET_IS_RETURN_P (x))); + if (x == NULL) + return false; + + switch (GET_CODE (x)) + { + case RETURN: + case EH_RETURN: + return true; + + case SET: + return SET_IS_RETURN_P (x); + + default: + return false; + } } +/* Return TRUE if INSN is a return jump. */ + int returnjump_p (rtx insn) { @@ -881,6 +899,22 @@ return for_each_rtx (&PATTERN (insn), returnjump_p_1, NULL); } +/* Return true if INSN is a (possibly conditional) return insn. */ + +static int +eh_returnjump_p_1 (rtx *loc, void *data ATTRIBUTE_UNUSED) +{ + return *loc && GET_CODE (*loc) == EH_RETURN; +} + +int +eh_returnjump_p (rtx insn) +{ + if (!JUMP_P (insn)) + return 0; + return for_each_rtx (&PATTERN (insn), eh_returnjump_p_1, NULL); +} + /* Return true if INSN is a jump that only transfers control and nothing more. */ @@ -973,8 +1007,12 @@ void mark_jump_label (rtx x, rtx insn, int in_mem) { - mark_jump_label_1 (x, insn, in_mem != 0, - (insn != NULL && x == PATTERN (insn) && JUMP_P (insn))); + rtx asmop = extract_asm_operands (x); + if (asmop) + mark_jump_label_asm (asmop, insn); + else + mark_jump_label_1 (x, insn, in_mem != 0, + (insn != NULL && x == PATTERN (insn) && JUMP_P (insn))); } /* Worker function for mark_jump_label. IN_MEM is TRUE when X occurs @@ -1112,6 +1150,22 @@ } } +/* Worker function for mark_jump_label. Handle asm insns specially. + In particular, output operands need not be considered so we can + avoid re-scanning the replicated asm_operand. Also, the asm_labels + need to be considered targets. */ + +static void +mark_jump_label_asm (rtx asmop, rtx insn) +{ + int i; + + for (i = ASM_OPERANDS_INPUT_LENGTH (asmop) - 1; i >= 0; --i) + mark_jump_label_1 (ASM_OPERANDS_INPUT (asmop, i), insn, false, false); + + for (i = ASM_OPERANDS_LABEL_LENGTH (asmop) - 1; i >= 0; --i) + mark_jump_label_1 (ASM_OPERANDS_LABEL (asmop, i), insn, false, true); +} /* Delete insn INSN from the chain of insns and update label ref counts and delete insns now unreachable. @@ -1167,9 +1221,7 @@ /* Likewise if we're deleting a dispatch table. */ - if (JUMP_P (insn) - && (GET_CODE (PATTERN (insn)) == ADDR_VEC - || GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC)) + if (JUMP_TABLE_DATA_P (insn)) { rtx pat = PATTERN (insn); int i, diff_vec_p = GET_CODE (pat) == ADDR_DIFF_VEC; @@ -1203,9 +1255,7 @@ if (was_code_label && NEXT_INSN (insn) != 0 - && JUMP_P (NEXT_INSN (insn)) - && (GET_CODE (PATTERN (NEXT_INSN (insn))) == ADDR_VEC - || GET_CODE (PATTERN (NEXT_INSN (insn))) == ADDR_DIFF_VEC)) + && JUMP_TABLE_DATA_P (NEXT_INSN (insn))) next = delete_related_insns (NEXT_INSN (insn)); /* If INSN was a label, delete insns following it if now unreachable. */ @@ -1357,9 +1407,17 @@ redirect_jump_1 (rtx jump, rtx nlabel) { int ochanges = num_validated_changes (); - rtx *loc; + rtx *loc, asmop; - if (GET_CODE (PATTERN (jump)) == PARALLEL) + asmop = extract_asm_operands (PATTERN (jump)); + if (asmop) + { + if (nlabel == NULL) + return 0; + gcc_assert (ASM_OPERANDS_LABEL_LENGTH (asmop) == 1); + loc = &ASM_OPERANDS_LABEL (asmop, 0); + } + else if (GET_CODE (PATTERN (jump)) == PARALLEL) loc = &XVECEXP (PATTERN (jump), 0, 0); else loc = &PATTERN (jump); @@ -1394,7 +1452,7 @@ } /* Fix up JUMP_LABEL and label ref counts after OLABEL has been replaced with - NLABEL in JUMP. + NLABEL in JUMP. If DELETE_UNUSED is positive, delete related insn to OLABEL if its ref count has dropped to zero. */ void @@ -1485,10 +1543,11 @@ int ok; ochanges = num_validated_changes (); - gcc_assert (x); + if (x == NULL) + return 0; ok = invert_exp_1 (SET_SRC (x), jump); gcc_assert (ok); - + if (num_validated_changes () == ochanges) return 0; @@ -1536,6 +1595,7 @@ { int reg_x = -1, reg_y = -1; int byte_x = 0, byte_y = 0; + struct subreg_info info; if (GET_MODE (x) != GET_MODE (y)) return 0; @@ -1552,15 +1612,12 @@ if (reg_renumber[reg_x] >= 0) { - if (!subreg_offset_representable_p (reg_renumber[reg_x], - GET_MODE (SUBREG_REG (x)), - byte_x, - GET_MODE (x))) + subreg_get_info (reg_renumber[reg_x], + GET_MODE (SUBREG_REG (x)), byte_x, + GET_MODE (x), &info); + if (!info.representable_p) return 0; - reg_x = subreg_regno_offset (reg_renumber[reg_x], - GET_MODE (SUBREG_REG (x)), - byte_x, - GET_MODE (x)); + reg_x = info.offset; byte_x = 0; } } @@ -1578,15 +1635,12 @@ if (reg_renumber[reg_y] >= 0) { - if (!subreg_offset_representable_p (reg_renumber[reg_y], - GET_MODE (SUBREG_REG (y)), - byte_y, - GET_MODE (y))) + subreg_get_info (reg_renumber[reg_y], + GET_MODE (SUBREG_REG (y)), byte_y, + GET_MODE (y), &info); + if (!info.representable_p) return 0; - reg_y = subreg_regno_offset (reg_renumber[reg_y], - GET_MODE (SUBREG_REG (y)), - byte_y, - GET_MODE (y)); + reg_y = info.offset; byte_y = 0; } } @@ -1641,6 +1695,10 @@ if (GET_MODE (x) != GET_MODE (y)) return 0; + /* MEMs refering to different address space are not equivalent. */ + if (code == MEM && MEM_ADDR_SPACE (x) != MEM_ADDR_SPACE (y)) + return 0; + /* For commutative operations, the RTX match if the operand match in any order. Also handle the simple binary and unary cases without a loop. */ if (targetm.commutative_p (x, UNKNOWN)) @@ -1728,13 +1786,17 @@ { int base = true_regnum (SUBREG_REG (x)); if (base >= 0 - && base < FIRST_PSEUDO_REGISTER - && subreg_offset_representable_p (REGNO (SUBREG_REG (x)), - GET_MODE (SUBREG_REG (x)), - SUBREG_BYTE (x), GET_MODE (x))) - return base + subreg_regno_offset (REGNO (SUBREG_REG (x)), - GET_MODE (SUBREG_REG (x)), - SUBREG_BYTE (x), GET_MODE (x)); + && base < FIRST_PSEUDO_REGISTER) + { + struct subreg_info info; + + subreg_get_info (REGNO (SUBREG_REG (x)), + GET_MODE (SUBREG_REG (x)), + SUBREG_BYTE (x), GET_MODE (x), &info); + + if (info.representable_p) + return base + info.offset; + } } return -1; }