X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=gcc%2Fpostreload.c;h=88d5234eef367da8eeb79050b1484965baa83fcd;hb=1e44e857e05c165f6f01aeb56a7a43ee765bfc99;hp=68443abda25da8f90f679d04059ea02ffe2b1ea7;hpb=f1e52ed6b2a91ff953156a63a5c4af70e17fb6a8;p=gcc.git diff --git a/gcc/postreload.c b/gcc/postreload.c index 68443abda25..88d5234eef3 100644 --- a/gcc/postreload.c +++ b/gcc/postreload.c @@ -20,29 +20,16 @@ along with GCC; see the file COPYING3. If not see #include "config.h" #include "system.h" #include "coretypes.h" -#include "tm.h" - -#include "machmode.h" -#include "hard-reg-set.h" +#include "backend.h" +#include "predict.h" +#include "tree.h" #include "rtl.h" +#include "df.h" + #include "tm_p.h" -#include "obstack.h" #include "insn-config.h" #include "flags.h" -#include "hashtab.h" -#include "hash-set.h" -#include "vec.h" -#include "input.h" -#include "function.h" -#include "symtab.h" -#include "statistics.h" -#include "double-int.h" -#include "real.h" -#include "fixed-value.h" #include "alias.h" -#include "wide-int.h" -#include "inchash.h" -#include "tree.h" #include "expmed.h" #include "dojump.h" #include "explow.h" @@ -54,23 +41,23 @@ along with GCC; see the file COPYING3. If not see #include "insn-codes.h" #include "optabs.h" #include "regs.h" -#include "predict.h" -#include "dominance.h" -#include "cfg.h" #include "cfgrtl.h" #include "cfgbuild.h" #include "cfgcleanup.h" -#include "basic-block.h" #include "reload.h" #include "recog.h" +#include "alloc-pool.h" #include "cselib.h" #include "diagnostic-core.h" #include "except.h" #include "target.h" #include "tree-pass.h" -#include "df.h" #include "dbgcnt.h" +#ifndef LOAD_EXTEND_OP +#define LOAD_EXTEND_OP(M) UNKNOWN +#endif + static int reload_cse_noop_set_p (rtx); static bool reload_cse_simplify (rtx_insn *, rtx); static void reload_cse_regs_1 (void); @@ -234,7 +221,7 @@ reload_cse_regs_1 (void) bool cfg_changed = false; basic_block bb; rtx_insn *insn; - rtx testreg = gen_rtx_REG (VOIDmode, -1); + rtx testreg = gen_rtx_REG (word_mode, LAST_VIRTUAL_REGISTER + 1); cselib_init (CSELIB_RECORD_MEMORY); init_alias_analysis (); @@ -271,9 +258,7 @@ reload_cse_simplify_set (rtx set, rtx_insn *insn) int old_cost; cselib_val *val; struct elt_loc_list *l; -#ifdef LOAD_EXTEND_OP enum rtx_code extend_op = UNKNOWN; -#endif bool speed = optimize_bb_for_speed_p (BLOCK_FOR_INSN (insn)); dreg = true_regnum (SET_DEST (set)); @@ -286,7 +271,6 @@ reload_cse_simplify_set (rtx set, rtx_insn *insn) dclass = REGNO_REG_CLASS (dreg); -#ifdef LOAD_EXTEND_OP /* When replacing a memory with a register, we need to honor assumptions that combine made wrt the contents of sign bits. We'll do this by generating an extend instruction instead of a reg->reg copy. Thus @@ -296,7 +280,6 @@ reload_cse_simplify_set (rtx set, rtx_insn *insn) && (extend_op = LOAD_EXTEND_OP (GET_MODE (src))) != UNKNOWN && !REG_P (SET_DEST (set))) return 0; -#endif val = cselib_lookup (src, GET_MODE (SET_DEST (set)), 0, VOIDmode); if (! val) @@ -309,7 +292,7 @@ reload_cse_simplify_set (rtx set, rtx_insn *insn) old_cost = register_move_cost (GET_MODE (src), REGNO_REG_CLASS (REGNO (src)), dclass); else - old_cost = set_src_cost (src, speed); + old_cost = set_src_cost (src, GET_MODE (SET_DEST (set)), speed); for (l = val->locs; l; l = l->next) { @@ -318,7 +301,6 @@ reload_cse_simplify_set (rtx set, rtx_insn *insn) if (CONSTANT_P (this_rtx) && ! references_value_p (this_rtx, 0)) { -#ifdef LOAD_EXTEND_OP if (extend_op != UNKNOWN) { wide_int result; @@ -343,19 +325,17 @@ reload_cse_simplify_set (rtx set, rtx_insn *insn) } this_rtx = immed_wide_int_const (result, word_mode); } -#endif - this_cost = set_src_cost (this_rtx, speed); + + this_cost = set_src_cost (this_rtx, GET_MODE (SET_DEST (set)), speed); } else if (REG_P (this_rtx)) { -#ifdef LOAD_EXTEND_OP if (extend_op != UNKNOWN) { this_rtx = gen_rtx_fmt_e (extend_op, word_mode, this_rtx); - this_cost = set_src_cost (this_rtx, speed); + this_cost = set_src_cost (this_rtx, word_mode, speed); } else -#endif this_cost = register_move_cost (GET_MODE (this_rtx), REGNO_REG_CLASS (REGNO (this_rtx)), dclass); @@ -370,7 +350,6 @@ reload_cse_simplify_set (rtx set, rtx_insn *insn) && REG_P (this_rtx) && !REG_P (SET_SRC (set)))) { -#ifdef LOAD_EXTEND_OP if (GET_MODE_BITSIZE (GET_MODE (SET_DEST (set))) < BITS_PER_WORD && extend_op != UNKNOWN #ifdef CANNOT_CHANGE_MODE_CLASS @@ -384,7 +363,6 @@ reload_cse_simplify_set (rtx set, rtx_insn *insn) ORIGINAL_REGNO (wide_dest) = ORIGINAL_REGNO (SET_DEST (set)); validate_change (insn, &SET_DEST (set), wide_dest, 1); } -#endif validate_unshare_change (insn, &SET_SRC (set), this_rtx, 1); old_cost = this_cost, did_change = 1; @@ -456,7 +434,6 @@ reload_cse_simplify_operands (rtx_insn *insn, rtx testreg) continue; op = recog_data.operand[i]; -#ifdef LOAD_EXTEND_OP if (MEM_P (op) && GET_MODE_BITSIZE (GET_MODE (op)) < BITS_PER_WORD && LOAD_EXTEND_OP (GET_MODE (op)) != UNKNOWN) @@ -507,7 +484,7 @@ reload_cse_simplify_operands (rtx_insn *insn, rtx testreg) safe to optimize, but is it worth the trouble? */ continue; } -#endif /* LOAD_EXTEND_OP */ + if (side_effects_p (op)) continue; v = cselib_lookup (op, recog_data.operand_mode[i], 0, VOIDmode); @@ -562,8 +539,7 @@ reload_cse_simplify_operands (rtx_insn *insn, rtx testreg) if (! TEST_HARD_REG_BIT (equiv_regs[i], regno)) continue; - SET_REGNO_RAW (testreg, regno); - PUT_MODE (testreg, mode); + set_mode_and_regno (testreg, mode, regno); /* We found a register equal to this operand. Now look for all alternatives that can accept this register and have not been @@ -596,10 +572,10 @@ reload_cse_simplify_operands (rtx_insn *insn, rtx testreg) && TEST_BIT (preferred, j) && reg_fits_class_p (testreg, rclass, 0, mode) && (!CONST_INT_P (recog_data.operand[i]) - || (set_src_cost (recog_data.operand[i], + || (set_src_cost (recog_data.operand[i], mode, optimize_bb_for_speed_p (BLOCK_FOR_INSN (insn))) - > set_src_cost (testreg, + > set_src_cost (testreg, mode, optimize_bb_for_speed_p (BLOCK_FOR_INSN (insn)))))) { @@ -632,7 +608,6 @@ reload_cse_simplify_operands (rtx_insn *insn, rtx testreg) int best = i; int best_reject = alternative_reject[alternative_order[i]]; int best_nregs = alternative_nregs[alternative_order[i]]; - int tmp; for (j = i + 1; j < recog_data.n_alternatives; j++) { @@ -648,9 +623,7 @@ reload_cse_simplify_operands (rtx_insn *insn, rtx testreg) } } - tmp = alternative_order[best]; - alternative_order[best] = alternative_order[i]; - alternative_order[i] = tmp; + std::swap (alternative_order[best], alternative_order[i]); } /* Substitute the operands as determined by op_alt_regno for the best @@ -935,12 +908,13 @@ try_replace_in_use (struct reg_use *use, rtx reg, rtx src) && CONSTANT_P (XEXP (SET_SRC (new_set), 1))) { rtx new_src; - int old_cost = set_src_cost (SET_SRC (new_set), speed); + machine_mode mode = GET_MODE (SET_DEST (new_set)); + int old_cost = set_src_cost (SET_SRC (new_set), mode, speed); gcc_assert (rtx_equal_p (XEXP (SET_SRC (new_set), 0), reg)); new_src = simplify_replace_rtx (SET_SRC (new_set), reg, src); - if (set_src_cost (new_src, speed) <= old_cost + if (set_src_cost (new_src, mode, speed) <= old_cost && validate_change (use_insn, &SET_SRC (new_set), new_src, 0)) return true; @@ -974,7 +948,7 @@ reload_combine_recognize_const_pattern (rtx_insn *insn) reg = SET_DEST (set); src = SET_SRC (set); if (!REG_P (reg) - || hard_regno_nregs[REGNO (reg)][GET_MODE (reg)] != 1 + || REG_NREGS (reg) != 1 || GET_MODE (reg) != Pmode || reg == stack_pointer_rtx) return false; @@ -1032,11 +1006,9 @@ reload_combine_recognize_const_pattern (rtx_insn *insn) && reg_state[clobbered_regno].real_store_ruid >= use_ruid) break; -#if HAVE_cc0 /* Do not separate cc0 setter and cc0 user on HAVE_cc0 targets. */ - if (must_move_add && sets_cc0_p (PATTERN (use_insn))) + if (HAVE_cc0 && must_move_add && sets_cc0_p (PATTERN (use_insn))) break; -#endif gcc_assert (reg_state[regno].store_ruid <= use_ruid); /* Avoid moving a use of ADDREG past a point where it is stored. */ @@ -1111,8 +1083,7 @@ reload_combine_recognize_pattern (rtx_insn *insn) reg = SET_DEST (set); src = SET_SRC (set); - if (!REG_P (reg) - || hard_regno_nregs[REGNO (reg)][GET_MODE (reg)] != 1) + if (!REG_P (reg) || REG_NREGS (reg) != 1) return false; regno = REGNO (reg); @@ -1363,9 +1334,12 @@ reload_combine (void) if (CALL_P (insn)) { rtx link; + HARD_REG_SET used_regs; + + get_call_reg_set_usage (insn, &used_regs, call_used_reg_set); for (r = 0; r < FIRST_PSEUDO_REGISTER; r++) - if (call_used_regs[r]) + if (TEST_HARD_REG_BIT (used_regs, r)) { reg_state[r].use_index = RELOAD_COMBINE_MAX_USES; reg_state[r].store_ruid = reload_combine_ruid; @@ -1379,12 +1353,8 @@ reload_combine (void) if ((GET_CODE (setuse) == USE || GET_CODE (setuse) == CLOBBER) && REG_P (usage_rtx)) { - unsigned int i; - unsigned int start_reg = REGNO (usage_rtx); - unsigned int num_regs - = hard_regno_nregs[start_reg][GET_MODE (usage_rtx)]; - unsigned int end_reg = start_reg + num_regs - 1; - for (i = start_reg; i <= end_reg; i++) + unsigned int end_regno = END_REGNO (usage_rtx); + for (unsigned int i = REGNO (usage_rtx); i < end_regno; ++i) if (GET_CODE (XEXP (link, 0)) == CLOBBER) { reg_state[i].use_index = RELOAD_COMBINE_MAX_USES; @@ -1466,9 +1436,8 @@ reload_combine_note_store (rtx dst, const_rtx set, void *data ATTRIBUTE_UNUSED) || GET_CODE (dst) == PRE_DEC || GET_CODE (dst) == POST_DEC || GET_CODE (dst) == PRE_MODIFY || GET_CODE (dst) == POST_MODIFY) { - regno = REGNO (XEXP (dst, 0)); - mode = GET_MODE (XEXP (dst, 0)); - for (i = hard_regno_nregs[regno][mode] - 1 + regno; i >= regno; i--) + unsigned int end_regno = END_REGNO (XEXP (dst, 0)); + for (unsigned int i = REGNO (XEXP (dst, 0)); i < end_regno; ++i) { /* We could probably do better, but for now mark the register as used in an unknown fashion and set/clobbered at this @@ -1538,13 +1507,11 @@ reload_combine_note_use (rtx *xp, rtx_insn *insn, int ruid, rtx containing_mem) /* If this is the USE of a return value, we can't change it. */ if (REG_P (XEXP (x, 0)) && REG_FUNCTION_VALUE_P (XEXP (x, 0))) { - /* Mark the return register as used in an unknown fashion. */ + /* Mark the return register as used in an unknown fashion. */ rtx reg = XEXP (x, 0); - int regno = REGNO (reg); - int nregs = hard_regno_nregs[regno][GET_MODE (reg)]; - - while (--nregs >= 0) - reg_state[regno + nregs].use_index = -1; + unsigned int end_regno = END_REGNO (reg); + for (unsigned int regno = REGNO (reg); regno < end_regno; ++regno) + reg_state[regno].use_index = -1; return; } break; @@ -1575,7 +1542,7 @@ reload_combine_note_use (rtx *xp, rtx_insn *insn, int ruid, rtx containing_mem) /* No spurious USEs of pseudo registers may remain. */ gcc_assert (regno < FIRST_PSEUDO_REGISTER); - nregs = hard_regno_nregs[regno][GET_MODE (x)]; + nregs = REG_NREGS (x); /* We can't substitute into multi-hard-reg uses. */ if (nregs > 1) @@ -1707,7 +1674,7 @@ move2add_record_mode (rtx reg) else if (REG_P (reg)) { regno = REGNO (reg); - nregs = hard_regno_nregs[regno][mode]; + nregs = REG_NREGS (reg); } else gcc_unreachable (); @@ -1824,8 +1791,7 @@ move2add_use_add2_insn (rtx reg, rtx sym, rtx off, rtx_insn *insn) rtx narrow_src = gen_int_mode (INTVAL (off), narrow_mode); rtx new_set - = gen_rtx_SET (VOIDmode, - gen_rtx_STRICT_LOW_PART (VOIDmode, + = gen_rtx_SET (gen_rtx_STRICT_LOW_PART (VOIDmode, narrow_reg), narrow_src); get_full_set_rtx_cost (new_set, &newcst); @@ -2046,14 +2012,14 @@ reload_cse_move2add (rtx_insn *first) get_full_set_rtx_cost (set, &oldcst); SET_SRC (set) = tem; - get_full_set_src_cost (tem, &newcst); + get_full_set_src_cost (tem, GET_MODE (reg), &newcst); SET_SRC (set) = old_src; costs_add_n_insns (&oldcst, 1); if (costs_lt_p (&newcst, &oldcst, speed) && have_add2_insn (reg, new_src)) { - rtx newpat = gen_rtx_SET (VOIDmode, reg, tem); + rtx newpat = gen_rtx_SET (reg, tem); success = validate_change (next, &PATTERN (next), newpat, 0); @@ -2148,11 +2114,11 @@ reload_cse_move2add (rtx_insn *first) number of calls to gen_rtx_SET to avoid memory allocation if possible. */ && SCALAR_INT_MODE_P (GET_MODE (XEXP (cnd, 0))) - && hard_regno_nregs[REGNO (XEXP (cnd, 0))][GET_MODE (XEXP (cnd, 0))] == 1 + && REG_NREGS (XEXP (cnd, 0)) == 1 && CONST_INT_P (XEXP (cnd, 1))) { rtx implicit_set = - gen_rtx_SET (VOIDmode, XEXP (cnd, 0), XEXP (cnd, 1)); + gen_rtx_SET (XEXP (cnd, 0), XEXP (cnd, 1)); move2add_note_store (SET_DEST (implicit_set), implicit_set, insn); } } @@ -2161,12 +2127,29 @@ reload_cse_move2add (rtx_insn *first) unknown values. */ if (CALL_P (insn)) { + rtx link; + for (i = FIRST_PSEUDO_REGISTER - 1; i >= 0; i--) { if (call_used_regs[i]) /* Reset the information about this register. */ reg_mode[i] = VOIDmode; } + + for (link = CALL_INSN_FUNCTION_USAGE (insn); link; + link = XEXP (link, 1)) + { + rtx setuse = XEXP (link, 0); + rtx usage_rtx = XEXP (setuse, 0); + if (GET_CODE (setuse) == CLOBBER + && REG_P (usage_rtx)) + { + unsigned int end_regno = END_REGNO (usage_rtx); + for (unsigned int r = REGNO (usage_rtx); r < end_regno; ++r) + /* Reset the information about this register. */ + reg_mode[r] = VOIDmode; + } + } } } return changed;