X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fregcprop.c;h=ceb46355359eaaa818c28e70902ab986d5aa7144;hb=a2b5b4504f74adb85f9120d66c92380c82fc5e6c;hp=0f0dfb3ce7804105ec72e9a0306f88b17fe02192;hpb=7521936724d5ab5b6ea41039406ddb2916bc70cc;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/regcprop.c b/gcc/regcprop.c index 0f0dfb3ce78..ceb46355359 100644 --- a/gcc/regcprop.c +++ b/gcc/regcprop.c @@ -98,7 +98,7 @@ static rtx find_oldest_value_reg (enum reg_class, rtx, struct value_data *); static bool replace_oldest_value_reg (rtx *, enum reg_class, rtx, struct value_data *); static bool replace_oldest_value_addr (rtx *, enum reg_class, - enum machine_mode, rtx, + enum machine_mode, addr_space_t, rtx, struct value_data *); static bool replace_oldest_value_mem (rtx, rtx, struct value_data *); static bool copyprop_hardreg_forward_1 (basic_block, struct value_data *); @@ -418,10 +418,9 @@ maybe_mode_change (enum machine_mode orig_mode, enum machine_mode copy_mode, offset = ((WORDS_BIG_ENDIAN ? wordoffset : 0) + (BYTES_BIG_ENDIAN ? byteoffset : 0)); - return gen_rtx_raw_REG (new_mode, - regno + subreg_regno_offset (regno, orig_mode, - offset, - new_mode)); + regno += subreg_regno_offset (regno, orig_mode, offset, new_mode); + if (HARD_REGNO_MODE_OK (regno, new_mode)) + return gen_rtx_raw_REG (new_mode, regno); } return NULL_RTX; } @@ -516,8 +515,8 @@ replace_oldest_value_reg (rtx *loc, enum reg_class cl, rtx insn, static bool replace_oldest_value_addr (rtx *loc, enum reg_class cl, - enum machine_mode mode, rtx insn, - struct value_data *vd) + enum machine_mode mode, addr_space_t as, + rtx insn, struct value_data *vd) { rtx x = *loc; RTX_CODE code = GET_CODE (x); @@ -586,15 +585,15 @@ replace_oldest_value_addr (rtx *loc, enum reg_class cl, unsigned regno0 = REGNO (op0), regno1 = REGNO (op1); if (REGNO_OK_FOR_INDEX_P (regno1) - && regno_ok_for_base_p (regno0, mode, PLUS, REG)) + && regno_ok_for_base_p (regno0, mode, as, PLUS, REG)) index_op = 1; else if (REGNO_OK_FOR_INDEX_P (regno0) - && regno_ok_for_base_p (regno1, mode, PLUS, REG)) + && regno_ok_for_base_p (regno1, mode, as, PLUS, REG)) index_op = 0; - else if (regno_ok_for_base_p (regno0, mode, PLUS, REG) + else if (regno_ok_for_base_p (regno0, mode, as, PLUS, REG) || REGNO_OK_FOR_INDEX_P (regno1)) index_op = 1; - else if (regno_ok_for_base_p (regno1, mode, PLUS, REG)) + else if (regno_ok_for_base_p (regno1, mode, as, PLUS, REG)) index_op = 0; else index_op = 1; @@ -617,13 +616,13 @@ replace_oldest_value_addr (rtx *loc, enum reg_class cl, } if (locI) - changed |= replace_oldest_value_addr (locI, INDEX_REG_CLASS, mode, - insn, vd); + changed |= replace_oldest_value_addr (locI, INDEX_REG_CLASS, + mode, as, insn, vd); if (locB) changed |= replace_oldest_value_addr (locB, - base_reg_class (mode, PLUS, + base_reg_class (mode, as, PLUS, index_code), - mode, insn, vd); + mode, as, insn, vd); return changed; } @@ -649,12 +648,12 @@ replace_oldest_value_addr (rtx *loc, enum reg_class cl, for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) { if (fmt[i] == 'e') - changed |= replace_oldest_value_addr (&XEXP (x, i), cl, mode, + changed |= replace_oldest_value_addr (&XEXP (x, i), cl, mode, as, insn, vd); else if (fmt[i] == 'E') for (j = XVECLEN (x, i) - 1; j >= 0; j--) changed |= replace_oldest_value_addr (&XVECEXP (x, i, j), cl, - mode, insn, vd); + mode, as, insn, vd); } return changed; @@ -670,10 +669,11 @@ replace_oldest_value_mem (rtx x, rtx insn, struct value_data *vd) if (DEBUG_INSN_P (insn)) cl = ALL_REGS; else - cl = base_reg_class (GET_MODE (x), MEM, SCRATCH); + cl = base_reg_class (GET_MODE (x), MEM_ADDR_SPACE (x), MEM, SCRATCH); return replace_oldest_value_addr (&XEXP (x, 0), cl, - GET_MODE (x), insn, vd); + GET_MODE (x), MEM_ADDR_SPACE (x), + insn, vd); } /* Apply all queued updates for DEBUG_INSNs that change some reg to @@ -752,7 +752,7 @@ copyprop_hardreg_forward_1 (basic_block bb, struct value_data *vd) if (!VAR_LOC_UNKNOWN_P (loc)) replace_oldest_value_addr (&INSN_VAR_LOCATION_LOC (insn), ALL_REGS, GET_MODE (loc), - insn, vd); + ADDR_SPACE_GENERIC, insn, vd); } if (insn == BB_END (bb)) @@ -825,6 +825,14 @@ copyprop_hardreg_forward_1 (basic_block bb, struct value_data *vd) if (hard_regno_nregs[regno][mode] > hard_regno_nregs[regno][vd->e[regno].mode]) goto no_move_special_case; + + /* And likewise, if we are narrowing on big endian the transformation + is also invalid. */ + if (hard_regno_nregs[regno][mode] + < hard_regno_nregs[regno][vd->e[regno].mode] + && (GET_MODE_SIZE (vd->e[regno].mode) > UNITS_PER_WORD + ? WORDS_BIG_ENDIAN : BYTES_BIG_ENDIAN)) + goto no_move_special_case; } /* If the destination is also a register, try to find a source @@ -841,6 +849,12 @@ copyprop_hardreg_forward_1 (basic_block bb, struct value_data *vd) changed = true; goto did_replacement; } + /* We need to re-extract as validate_change clobbers + recog_data. */ + extract_insn (insn); + if (! constrain_operands (1)) + fatal_insn_not_found (insn); + preprocess_constraints (); } /* Otherwise, try all valid registers and see if its valid. */ @@ -863,6 +877,12 @@ copyprop_hardreg_forward_1 (basic_block bb, struct value_data *vd) changed = true; goto did_replacement; } + /* We need to re-extract as validate_change clobbers + recog_data. */ + extract_insn (insn); + if (! constrain_operands (1)) + fatal_insn_not_found (insn); + preprocess_constraints (); } } } @@ -894,7 +914,8 @@ copyprop_hardreg_forward_1 (basic_block bb, struct value_data *vd) replaced[i] = replace_oldest_value_addr (recog_data.operand_loc[i], recog_op_alt[i][alt].cl, - VOIDmode, insn, vd); + VOIDmode, ADDR_SPACE_GENERIC, + insn, vd); else if (REG_P (recog_data.operand[i])) replaced[i] = replace_oldest_value_reg (recog_data.operand_loc[i], @@ -990,7 +1011,7 @@ copyprop_hardreg_forward (void) visited = sbitmap_alloc (last_basic_block); sbitmap_zero (visited); - if (MAY_HAVE_DEBUG_STMTS) + if (MAY_HAVE_DEBUG_INSNS) debug_insn_changes_pool = create_alloc_pool ("debug insn changes pool", sizeof (struct queued_debug_insn_change), 256); @@ -1029,7 +1050,7 @@ copyprop_hardreg_forward (void) copyprop_hardreg_forward_1 (bb, all_vd + bb->index); } - if (MAY_HAVE_DEBUG_STMTS) + if (MAY_HAVE_DEBUG_INSNS) { FOR_EACH_BB (bb) if (TEST_BIT (visited, bb->index) @@ -1188,7 +1209,7 @@ struct rtl_opt_pass pass_cprop_hardreg = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func | TODO_df_finish + TODO_df_finish | TODO_verify_rtl_sharing /* todo_flags_finish */ } };