Mercurial > hg > CbC > CbC_gcc
diff gcc/reload.c @ 131:84e7813d76e9
gcc-8.2
author | mir3636 |
---|---|
date | Thu, 25 Oct 2018 07:37:49 +0900 |
parents | 04ced10e8804 |
children | 1830386684a0 |
line wrap: on
line diff
--- a/gcc/reload.c Fri Oct 27 22:46:09 2017 +0900 +++ b/gcc/reload.c Thu Oct 25 07:37:49 2018 +0900 @@ -1,5 +1,5 @@ /* Search an insn for pseudo regs that must be in hard regs and are not. - Copyright (C) 1987-2017 Free Software Foundation, Inc. + Copyright (C) 1987-2018 Free Software Foundation, Inc. This file is part of GCC. @@ -168,8 +168,8 @@ int reg_flag; /* Nonzero if referencing a register. */ int safe; /* Nonzero if this can't conflict with anything. */ rtx base; /* Base address for MEM. */ - HOST_WIDE_INT start; /* Starting offset or register number. */ - HOST_WIDE_INT end; /* Ending offset or register number. */ + poly_int64_pod start; /* Starting offset or register number. */ + poly_int64_pod end; /* Ending offset or register number. */ }; /* Save MEMs needed to copy from one class of registers to another. One MEM @@ -278,7 +278,7 @@ static rtx find_reloads_subreg_address (rtx, int, enum reload_type, int, rtx_insn *, int *); static void copy_replacements_1 (rtx *, rtx *, int); -static int find_inc_amount (rtx, rtx); +static poly_int64 find_inc_amount (rtx, rtx); static int refers_to_mem_for_reload_p (rtx); static int refers_to_regno_for_reload_p (unsigned int, unsigned int, rtx, rtx *); @@ -811,6 +811,25 @@ return n_reloads; } +/* Return true if: + + (a) (subreg:OUTER_MODE REG ...) represents a word or subword subreg + of a multiword value; and + + (b) the number of *words* in REG does not match the number of *registers* + in REG. */ + +static bool +complex_word_subreg_p (machine_mode outer_mode, rtx reg) +{ + machine_mode inner_mode = GET_MODE (reg); + poly_uint64 reg_words = REG_NREGS (reg) * UNITS_PER_WORD; + return (known_le (GET_MODE_SIZE (outer_mode), UNITS_PER_WORD) + && maybe_gt (GET_MODE_SIZE (inner_mode), UNITS_PER_WORD) + && !known_equal_after_align_up (GET_MODE_SIZE (inner_mode), + reg_words, UNITS_PER_WORD)); +} + /* Return true if X is a SUBREG that will need reloading of its SUBREG_REG expression. MODE is the mode that X will be used in. OUTPUT is true if the function is invoked for the output part of an enclosing reload. */ @@ -842,11 +861,7 @@ INNER is larger than a word and the number of registers in INNER is not the same as the number of words in INNER, then INNER will need reloading (with an in-out reload). */ - return (output - && GET_MODE_SIZE (mode) <= UNITS_PER_WORD - && GET_MODE_SIZE (GET_MODE (inner)) > UNITS_PER_WORD - && ((GET_MODE_SIZE (GET_MODE (inner)) / UNITS_PER_WORD) - != REG_NREGS (inner))); + return output && complex_word_subreg_p (mode, inner); } /* Return nonzero if IN can be reloaded into REGNO with mode MODE without @@ -1048,7 +1063,7 @@ && REGNO (SUBREG_REG (in)) >= FIRST_PSEUDO_REGISTER) || MEM_P (SUBREG_REG (in))) && (paradoxical_subreg_p (inmode, GET_MODE (SUBREG_REG (in))) - || (GET_MODE_SIZE (inmode) <= UNITS_PER_WORD + || (known_le (GET_MODE_SIZE (inmode), UNITS_PER_WORD) && is_a <scalar_int_mode> (GET_MODE (SUBREG_REG (in)), &inner_mode) && GET_MODE_SIZE (inner_mode) <= UNITS_PER_WORD @@ -1056,20 +1071,16 @@ && LOAD_EXTEND_OP (inner_mode) != UNKNOWN) || (WORD_REGISTER_OPERATIONS && partial_subreg_p (inmode, GET_MODE (SUBREG_REG (in))) - && ((GET_MODE_SIZE (inmode) - 1) / UNITS_PER_WORD == - ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (in))) - 1) - / UNITS_PER_WORD))))) + && (known_equal_after_align_down + (GET_MODE_SIZE (inmode) - 1, + GET_MODE_SIZE (GET_MODE (SUBREG_REG (in))) - 1, + UNITS_PER_WORD))))) || (REG_P (SUBREG_REG (in)) && REGNO (SUBREG_REG (in)) < FIRST_PSEUDO_REGISTER /* The case where out is nonzero is handled differently in the following statement. */ && (out == 0 || subreg_lowpart_p (in)) - && ((GET_MODE_SIZE (inmode) <= UNITS_PER_WORD - && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (in))) - > UNITS_PER_WORD) - && ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (in))) - / UNITS_PER_WORD) - != REG_NREGS (SUBREG_REG (in)))) + && (complex_word_subreg_p (inmode, SUBREG_REG (in)) || !targetm.hard_regno_mode_ok (subreg_regno (in), inmode))) || (secondary_reload_class (1, rclass, inmode, in) != NO_REGS && (secondary_reload_class (1, rclass, GET_MODE (SUBREG_REG (in)), @@ -1091,7 +1102,8 @@ && MEM_P (in)) /* This is supposed to happen only for paradoxical subregs made by combine.c. (SUBREG (MEM)) isn't supposed to occur other ways. */ - gcc_assert (GET_MODE_SIZE (GET_MODE (in)) <= GET_MODE_SIZE (inmode)); + gcc_assert (known_le (GET_MODE_SIZE (GET_MODE (in)), + GET_MODE_SIZE (inmode))); inmode = GET_MODE (in); } @@ -1150,16 +1162,17 @@ && (paradoxical_subreg_p (outmode, GET_MODE (SUBREG_REG (out))) || (WORD_REGISTER_OPERATIONS && partial_subreg_p (outmode, GET_MODE (SUBREG_REG (out))) - && ((GET_MODE_SIZE (outmode) - 1) / UNITS_PER_WORD == - ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (out))) - 1) - / UNITS_PER_WORD))))) + && (known_equal_after_align_down + (GET_MODE_SIZE (outmode) - 1, + GET_MODE_SIZE (GET_MODE (SUBREG_REG (out))) - 1, + UNITS_PER_WORD))))) || (REG_P (SUBREG_REG (out)) && REGNO (SUBREG_REG (out)) < FIRST_PSEUDO_REGISTER /* The case of a word mode subreg is handled differently in the following statement. */ - && ! (GET_MODE_SIZE (outmode) <= UNITS_PER_WORD - && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (out))) - > UNITS_PER_WORD)) + && ! (known_le (GET_MODE_SIZE (outmode), UNITS_PER_WORD) + && maybe_gt (GET_MODE_SIZE (GET_MODE (SUBREG_REG (out))), + UNITS_PER_WORD)) && !targetm.hard_regno_mode_ok (subreg_regno (out), outmode)) || (secondary_reload_class (0, rclass, outmode, out) != NO_REGS && (secondary_reload_class (0, rclass, GET_MODE (SUBREG_REG (out)), @@ -1177,8 +1190,8 @@ outloc = &SUBREG_REG (out); out = *outloc; gcc_assert (WORD_REGISTER_OPERATIONS || !MEM_P (out) - || GET_MODE_SIZE (GET_MODE (out)) - <= GET_MODE_SIZE (outmode)); + || known_le (GET_MODE_SIZE (GET_MODE (out)), + GET_MODE_SIZE (outmode))); outmode = GET_MODE (out); } @@ -1532,8 +1545,8 @@ value for the incoming operand (same as outgoing one). */ if (rld[i].reg_rtx == out && (REG_P (in) || CONSTANT_P (in)) - && 0 != find_equiv_reg (in, this_insn, NO_REGS, REGNO (out), - static_reload_reg_p, i, inmode)) + && find_equiv_reg (in, this_insn, NO_REGS, REGNO (out), + static_reload_reg_p, i, inmode) != 0) rld[i].in = out; } @@ -1585,13 +1598,13 @@ What's going on here. */ && (in != out || (GET_CODE (in) == SUBREG - && (((GET_MODE_SIZE (GET_MODE (in)) + (UNITS_PER_WORD - 1)) - / UNITS_PER_WORD) - == ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (in))) - + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD)))) + && (known_equal_after_align_up + (GET_MODE_SIZE (GET_MODE (in)), + GET_MODE_SIZE (GET_MODE (SUBREG_REG (in))), + UNITS_PER_WORD)))) /* Make sure the operand fits in the reg that dies. */ - && (GET_MODE_SIZE (rel_mode) - <= GET_MODE_SIZE (GET_MODE (XEXP (note, 0)))) + && known_le (GET_MODE_SIZE (rel_mode), + GET_MODE_SIZE (GET_MODE (XEXP (note, 0)))) && targetm.hard_regno_mode_ok (regno, inmode) && targetm.hard_regno_mode_ok (regno, outmode)) { @@ -1772,7 +1785,7 @@ && (ira_reg_class_max_nregs [(int)rld[i].rclass][(int) rld[i].inmode] == ira_reg_class_max_nregs [(int) rld[output_reload].rclass] [(int) rld[output_reload].outmode]) - && rld[i].inc == 0 + && known_eq (rld[i].inc, 0) && rld[i].reg_rtx == 0 /* Don't combine two reloads with different secondary memory locations. */ @@ -1929,9 +1942,9 @@ /* If operands exceed a word, we can't use either of them unless they have the same size. */ - if (GET_MODE_SIZE (outmode) != GET_MODE_SIZE (inmode) - && (GET_MODE_SIZE (outmode) > UNITS_PER_WORD - || GET_MODE_SIZE (inmode) > UNITS_PER_WORD)) + if (maybe_ne (GET_MODE_SIZE (outmode), GET_MODE_SIZE (inmode)) + && (maybe_gt (GET_MODE_SIZE (outmode), UNITS_PER_WORD) + || maybe_gt (GET_MODE_SIZE (inmode), UNITS_PER_WORD))) return 0; /* Note that {in,out}_offset are needed only when 'in' or 'out' @@ -2307,6 +2320,11 @@ return 0; break; + case 'p': + if (maybe_ne (SUBREG_BYTE (x), SUBREG_BYTE (y))) + return 0; + break; + case 'e': val = operands_match_p (XEXP (x, i), XEXP (y, i)); if (val == 0) @@ -2355,7 +2373,7 @@ decompose (rtx x) { struct decomposition val; - int all_const = 0; + int all_const = 0, regno; memset (&val, 0, sizeof (val)); @@ -2453,29 +2471,33 @@ case REG: val.reg_flag = 1; - val.start = true_regnum (x); - if (val.start < 0 || val.start >= FIRST_PSEUDO_REGISTER) + regno = true_regnum (x); + if (regno < 0 || regno >= FIRST_PSEUDO_REGISTER) { /* A pseudo with no hard reg. */ val.start = REGNO (x); val.end = val.start + 1; } else - /* A hard reg. */ - val.end = end_hard_regno (GET_MODE (x), val.start); + { + /* A hard reg. */ + val.start = regno; + val.end = end_hard_regno (GET_MODE (x), regno); + } break; case SUBREG: if (!REG_P (SUBREG_REG (x))) /* This could be more precise, but it's good enough. */ return decompose (SUBREG_REG (x)); - val.reg_flag = 1; - val.start = true_regnum (x); - if (val.start < 0 || val.start >= FIRST_PSEUDO_REGISTER) + regno = true_regnum (x); + if (regno < 0 || regno >= FIRST_PSEUDO_REGISTER) return decompose (SUBREG_REG (x)); - else - /* A hard reg. */ - val.end = val.start + subreg_nregs (x); + + /* A hard reg. */ + val.reg_flag = 1; + val.start = regno; + val.end = regno + subreg_nregs (x); break; case SCRATCH: @@ -2500,7 +2522,11 @@ struct decomposition xdata; if (ydata.reg_flag) - return !refers_to_regno_for_reload_p (ydata.start, ydata.end, x, (rtx*) 0); + /* In this case the decomposition structure contains register + numbers rather than byte offsets. */ + return !refers_to_regno_for_reload_p (ydata.start.to_constant (), + ydata.end.to_constant (), + x, (rtx *) 0); if (ydata.safe) return 1; @@ -2531,7 +2557,7 @@ return 0; } - return (xdata.start >= ydata.end || ydata.start >= xdata.end); + return known_ge (xdata.start, ydata.end) || known_ge (ydata.start, xdata.end); } /* Similar, but calls decompose. */ @@ -2864,8 +2890,8 @@ if (replace && MEM_P (op) && REG_P (reg) - && (GET_MODE_SIZE (GET_MODE (reg)) - >= GET_MODE_SIZE (GET_MODE (op))) + && known_ge (GET_MODE_SIZE (GET_MODE (reg)), + GET_MODE_SIZE (GET_MODE (op))) && reg_equiv_constant (REGNO (reg)) == 0) set_unique_reg_note (emit_insn_before (gen_rtx_USE (VOIDmode, reg), insn), @@ -3100,13 +3126,14 @@ || (REG_P (operand) && REGNO (operand) >= FIRST_PSEUDO_REGISTER)) && (WORD_REGISTER_OPERATIONS - || ((GET_MODE_BITSIZE (GET_MODE (operand)) - < BIGGEST_ALIGNMENT) - && paradoxical_subreg_p (operand_mode[i], - GET_MODE (operand))) + || (((maybe_lt + (GET_MODE_BITSIZE (GET_MODE (operand)), + BIGGEST_ALIGNMENT)) + && (paradoxical_subreg_p + (operand_mode[i], GET_MODE (operand))))) || BYTES_BIG_ENDIAN - || ((GET_MODE_SIZE (operand_mode[i]) - <= UNITS_PER_WORD) + || (known_le (GET_MODE_SIZE (operand_mode[i]), + UNITS_PER_WORD) && (is_a <scalar_int_mode> (GET_MODE (operand), &inner_mode)) && (GET_MODE_SIZE (inner_mode) @@ -3603,7 +3630,7 @@ if (! win && ! did_match && this_alternative[i] != NO_REGS - && GET_MODE_SIZE (operand_mode[i]) <= UNITS_PER_WORD + && known_le (GET_MODE_SIZE (operand_mode[i]), UNITS_PER_WORD) && reg_class_size [(int) preferred_class[i]] > 0 && ! small_register_class_p (preferred_class[i])) { @@ -6095,7 +6122,7 @@ int regno = REGNO (SUBREG_REG (x)); int reloaded = 0; rtx tem, orig; - int offset; + poly_int64 offset; gcc_assert (reg_equiv_memory_loc (regno) != 0); @@ -6124,8 +6151,9 @@ if (WORD_REGISTER_OPERATIONS && partial_subreg_p (outer_mode, inner_mode) - && ((GET_MODE_SIZE (outer_mode) - 1) / UNITS_PER_WORD - == (GET_MODE_SIZE (inner_mode) - 1) / UNITS_PER_WORD)) + && known_equal_after_align_down (GET_MODE_SIZE (outer_mode) - 1, + GET_MODE_SIZE (inner_mode) - 1, + UNITS_PER_WORD)) return NULL; /* Since we don't attempt to handle paradoxical subregs, we can just @@ -6142,7 +6170,7 @@ XEXP (tem, 0), &XEXP (tem, 0), opnum, type, ind_levels, insn); /* ??? Do we need to handle nonzero offsets somehow? */ - if (!offset && !rtx_equal_p (tem, orig)) + if (known_eq (offset, 0) && !rtx_equal_p (tem, orig)) push_reg_equiv_alt_mem (regno, tem); /* For some processors an address may be valid in the original mode but @@ -6750,9 +6778,8 @@ && CONST_DOUBLE_AS_FLOAT_P (XEXP (tem, 0)) && SCALAR_FLOAT_MODE_P (GET_MODE (XEXP (tem, 0))) && CONST_INT_P (goal) - && 0 != (goaltry - = operand_subword (XEXP (tem, 0), 0, 0, - VOIDmode)) + && (goaltry = operand_subword (XEXP (tem, 0), 0, + 0, VOIDmode)) != 0 && rtx_equal_p (goal, goaltry) && (valtry = operand_subword (SET_DEST (pat), 0, 0, @@ -6764,8 +6791,8 @@ && CONST_DOUBLE_AS_FLOAT_P (XEXP (tem, 0)) && SCALAR_FLOAT_MODE_P (GET_MODE (XEXP (tem, 0))) && CONST_INT_P (goal) - && 0 != (goaltry = operand_subword (XEXP (tem, 0), 1, 0, - VOIDmode)) + && (goaltry = operand_subword (XEXP (tem, 0), 1, 0, + VOIDmode)) != 0 && rtx_equal_p (goal, goaltry) && (valtry = operand_subword (SET_DEST (pat), 1, 0, VOIDmode)) @@ -7058,7 +7085,7 @@ within X, and return the amount INCED is incremented or decremented by. The value is always positive. */ -static int +static poly_int64 find_inc_amount (rtx x, rtx inced) { enum rtx_code code = GET_CODE (x); @@ -7091,8 +7118,8 @@ { if (fmt[i] == 'e') { - int tem = find_inc_amount (XEXP (x, i), inced); - if (tem != 0) + poly_int64 tem = find_inc_amount (XEXP (x, i), inced); + if (maybe_ne (tem, 0)) return tem; } if (fmt[i] == 'E') @@ -7100,8 +7127,8 @@ int j; for (j = XVECLEN (x, i) - 1; j >= 0; j--) { - int tem = find_inc_amount (XVECEXP (x, i, j), inced); - if (tem != 0) + poly_int64 tem = find_inc_amount (XVECEXP (x, i, j), inced); + if (maybe_ne (tem, 0)) return tem; } } @@ -7262,8 +7289,11 @@ if (rld[r].nongroup) fprintf (f, ", nongroup"); - if (rld[r].inc != 0) - fprintf (f, ", inc by %d", rld[r].inc); + if (maybe_ne (rld[r].inc, 0)) + { + fprintf (f, ", inc by "); + print_dec (rld[r].inc, f, SIGNED); + } if (rld[r].nocombine) fprintf (f, ", can't combine");