diff options
Diffstat (limited to 'gcc-4.9/gcc')
-rw-r--r-- | gcc-4.9/gcc/BASE-VER | 2 | ||||
-rw-r--r-- | gcc-4.9/gcc/config/aarch64/aarch64.c | 136 | ||||
-rw-r--r-- | gcc-4.9/gcc/config/i386/i386.c | 5 | ||||
-rw-r--r-- | gcc-4.9/gcc/expmed.c | 37 | ||||
-rw-r--r-- | gcc-4.9/gcc/lra-constraints.c | 21 | ||||
-rw-r--r-- | gcc-4.9/gcc/tree-ssa-loop-niter.c | 16 |
6 files changed, 132 insertions, 85 deletions
diff --git a/gcc-4.9/gcc/BASE-VER b/gcc-4.9/gcc/BASE-VER index d81d21ceb..86a9588ad 100644 --- a/gcc-4.9/gcc/BASE-VER +++ b/gcc-4.9/gcc/BASE-VER @@ -1 +1 @@ -4.9.x-google +4.9 diff --git a/gcc-4.9/gcc/config/aarch64/aarch64.c b/gcc-4.9/gcc/config/aarch64/aarch64.c index 09f2d2c5d..709799406 100644 --- a/gcc-4.9/gcc/config/aarch64/aarch64.c +++ b/gcc-4.9/gcc/config/aarch64/aarch64.c @@ -4825,6 +4825,80 @@ aarch64_rtx_arith_op_extract_p (rtx x, enum machine_mode mode) return false; } +/* Calculate the cost of calculating (if_then_else (OP0) (OP1) (OP2)), + storing it in *COST. Result is true if the total cost of the operation + has now been calculated. */ +static bool +aarch64_if_then_else_costs (rtx op0, rtx op1, rtx op2, int *cost, bool speed) +{ + rtx inner; + rtx comparator; + enum rtx_code cmpcode; + + if (COMPARISON_P (op0)) + { + inner = XEXP (op0, 0); + comparator = XEXP (op0, 1); + cmpcode = GET_CODE (op0); + } + else + { + inner = op0; + comparator = const0_rtx; + cmpcode = NE; + } + + if (GET_CODE (op1) == PC || GET_CODE (op2) == PC) + { + /* Conditional branch. */ + if (GET_MODE_CLASS (GET_MODE (inner)) == MODE_CC) + return true; + else + { + if (cmpcode == NE || cmpcode == EQ) + { + if (comparator == const0_rtx) + { + /* TBZ/TBNZ/CBZ/CBNZ. */ + if (GET_CODE (inner) == ZERO_EXTRACT) + /* TBZ/TBNZ. */ + *cost += rtx_cost (XEXP (inner, 0), + ZERO_EXTRACT, 0, speed); + else + /* CBZ/CBNZ. */ + *cost += rtx_cost (inner, cmpcode, 0, speed); + + return true; + } + } + else if (cmpcode == LT || cmpcode == GE) + { + /* TBZ/TBNZ. */ + if (comparator == const0_rtx) + return true; + } + } + } + else if (GET_MODE_CLASS (GET_MODE (inner)) == MODE_CC) + { + /* It's a conditional operation based on the status flags, + so it must be some flavor of CSEL. */ + + /* CSNEG, CSINV, and CSINC are handled for free as part of CSEL. */ + if (GET_CODE (op1) == NEG + || GET_CODE (op1) == NOT + || (GET_CODE (op1) == PLUS && XEXP (op1, 1) == const1_rtx)) + op1 = XEXP (op1, 0); + + *cost += rtx_cost (op1, IF_THEN_ELSE, 1, speed); + *cost += rtx_cost (op2, IF_THEN_ELSE, 2, speed); + return true; + } + + /* We don't know what this is, cost all operands. */ + return false; +} + /* Calculate the cost of calculating X, storing it in *COST. Result is true if the total cost of the operation has now been calculated. */ static bool @@ -5572,66 +5646,8 @@ cost_plus: return false; /* All arguments need to be in registers. */ case IF_THEN_ELSE: - op2 = XEXP (x, 2); - op0 = XEXP (x, 0); - op1 = XEXP (x, 1); - - if (GET_CODE (op1) == PC || GET_CODE (op2) == PC) - { - /* Conditional branch. */ - if (GET_MODE_CLASS (GET_MODE (XEXP (op0, 0))) == MODE_CC) - return true; - else - { - if (GET_CODE (op0) == NE - || GET_CODE (op0) == EQ) - { - rtx inner = XEXP (op0, 0); - rtx comparator = XEXP (op0, 1); - - if (comparator == const0_rtx) - { - /* TBZ/TBNZ/CBZ/CBNZ. */ - if (GET_CODE (inner) == ZERO_EXTRACT) - /* TBZ/TBNZ. */ - *cost += rtx_cost (XEXP (inner, 0), ZERO_EXTRACT, - 0, speed); - else - /* CBZ/CBNZ. */ - *cost += rtx_cost (inner, GET_CODE (op0), 0, speed); - - return true; - } - } - else if (GET_CODE (op0) == LT - || GET_CODE (op0) == GE) - { - rtx comparator = XEXP (op0, 1); - - /* TBZ/TBNZ. */ - if (comparator == const0_rtx) - return true; - } - } - } - else if (GET_MODE_CLASS (GET_MODE (XEXP (op0, 0))) == MODE_CC) - { - /* It's a conditional operation based on the status flags, - so it must be some flavor of CSEL. */ - - /* CSNEG, CSINV, and CSINC are handled for free as part of CSEL. */ - if (GET_CODE (op1) == NEG - || GET_CODE (op1) == NOT - || (GET_CODE (op1) == PLUS && XEXP (op1, 1) == const1_rtx)) - op1 = XEXP (op1, 0); - - *cost += rtx_cost (op1, IF_THEN_ELSE, 1, speed); - *cost += rtx_cost (op2, IF_THEN_ELSE, 2, speed); - return true; - } - - /* We don't know what this is, cost all operands. */ - return false; + return aarch64_if_then_else_costs (XEXP (x, 0), XEXP (x, 1), + XEXP (x, 2), cost, speed); case EQ: case NE: diff --git a/gcc-4.9/gcc/config/i386/i386.c b/gcc-4.9/gcc/config/i386/i386.c index a3c88ce64..9f57c6e3a 100644 --- a/gcc-4.9/gcc/config/i386/i386.c +++ b/gcc-4.9/gcc/config/i386/i386.c @@ -4252,8 +4252,7 @@ ix86_option_override_internal (bool main_args_p, /* Handle stack protector */ if (!opts_set->x_ix86_stack_protector_guard) - opts->x_ix86_stack_protector_guard - = TARGET_HAS_BIONIC ? SSP_GLOBAL : SSP_TLS; + opts->x_ix86_stack_protector_guard = SSP_TLS; /* Handle -mmemcpy-strategy= and -mmemset-strategy= */ if (opts->x_ix86_tune_memcpy_strategy) @@ -11310,7 +11309,7 @@ ix86_set_fp_insn () ix86_compute_frame_layout (&frame); gcc_assert (frame_pointer_partially_needed); - offset = frame.stack_pointer_offset - frame.hard_frame_pointer_offset; + offset = frame.stack_pointer_offset - frame.hard_frame_pointer_offset; if (TARGET_64BIT && (offset > 0x7fffffff)) { diff --git a/gcc-4.9/gcc/expmed.c b/gcc-4.9/gcc/expmed.c index 0124a213b..ad39034dd 100644 --- a/gcc-4.9/gcc/expmed.c +++ b/gcc-4.9/gcc/expmed.c @@ -113,7 +113,7 @@ init_expmed_one_conv (struct init_expmed_rtl *all, enum machine_mode to_mode, - (GET_MODE_CLASS (to_mode) == MODE_PARTIAL_INT)); from_size = (GET_MODE_BITSIZE (from_mode) - (GET_MODE_CLASS (from_mode) == MODE_PARTIAL_INT)); - + /* Assume cost of zero-extend and sign-extend is the same. */ which = (to_size < from_size ? &all->trunc : &all->zext); @@ -679,13 +679,28 @@ store_bit_field_1 (rtx str_rtx, unsigned HOST_WIDE_INT bitsize, || (bitsize % BITS_PER_WORD == 0 && bitnum % BITS_PER_WORD == 0))) { /* Use the subreg machinery either to narrow OP0 to the required - words or to cope with mode punning between equal-sized modes. */ - rtx sub = simplify_gen_subreg (fieldmode, op0, GET_MODE (op0), - bitnum / BITS_PER_UNIT); - if (sub) + words or to cope with mode punning between equal-sized modes. + In the latter case, use subreg on the rhs side, not lhs. */ + rtx sub; + + if (bitsize == GET_MODE_BITSIZE (GET_MODE (op0))) { - emit_move_insn (sub, value); - return true; + sub = simplify_gen_subreg (GET_MODE (op0), value, fieldmode, 0); + if (sub) + { + emit_move_insn (op0, sub); + return true; + } + } + else + { + sub = simplify_gen_subreg (fieldmode, op0, GET_MODE (op0), + bitnum / BITS_PER_UNIT); + if (sub) + { + emit_move_insn (sub, value); + return true; + } } } @@ -1755,7 +1770,7 @@ extract_bit_field (rtx str_rtx, unsigned HOST_WIDE_INT bitsize, return convert_extracted_bit_field (result, mode, tmode, unsignedp); } - + return extract_bit_field_1 (str_rtx, bitsize, bitnum, unsignedp, target, mode, tmode, true); } @@ -1899,7 +1914,7 @@ lshift_value (enum machine_mode mode, unsigned HOST_WIDE_INT value, int bitpos) { double_int val; - + val = double_int::from_uhwi (value); val = val.llshift (bitpos, HOST_BITS_PER_DOUBLE_INT); @@ -3372,7 +3387,7 @@ choose_multiplier (unsigned HOST_WIDE_INT d, int n, int precision, /* mlow = 2^(N + lgup)/d */ double_int val = double_int_zero.set_bit (pow); - mlow = val.div (double_int::from_uhwi (d), true, TRUNC_DIV_EXPR); + mlow = val.div (double_int::from_uhwi (d), true, TRUNC_DIV_EXPR); /* mhigh = (2^(N + lgup) + 2^(N + lgup - precision))/d */ val |= double_int_zero.set_bit (pow2); @@ -4033,7 +4048,7 @@ expand_divmod (int rem_flag, enum tree_code code, enum machine_mode mode, /* Only deduct something for a REM if the last divide done was for a different constant. Then set the constant of the last divide. */ - max_cost = (unsignedp + max_cost = (unsignedp ? udiv_cost (speed, compute_mode) : sdiv_cost (speed, compute_mode)); if (rem_flag && ! (last_div_const != 0 && op1_is_constant diff --git a/gcc-4.9/gcc/lra-constraints.c b/gcc-4.9/gcc/lra-constraints.c index c55cefecb..f19542411 100644 --- a/gcc-4.9/gcc/lra-constraints.c +++ b/gcc-4.9/gcc/lra-constraints.c @@ -456,7 +456,7 @@ static void update_equiv (int regno) { rtx x; - + if ((x = ira_reg_equiv[regno].memory) != NULL_RTX) ira_reg_equiv[regno].memory = simplify_replace_fn_rtx (x, NULL_RTX, loc_equivalence_callback, @@ -886,7 +886,7 @@ match_reload (signed char out, signed char *ins, enum reg_class goal_class, if (GET_CODE (in_rtx) == SUBREG) { rtx subreg_reg = SUBREG_REG (in_rtx); - + /* If SUBREG_REG is dying here and sub-registers IN_RTX and NEW_IN_REG are similar, we can use the same hard register for REG and SUBREG_REG. */ @@ -1699,7 +1699,7 @@ process_alt_operands (int only_alternative) if (only_alternative >= 0 && nalt != only_alternative) continue; - + overall = losers = reject = reload_nregs = reload_sum = 0; for (nop = 0; nop < n_operands; nop++) { @@ -2473,7 +2473,7 @@ process_alt_operands (int only_alternative) #ifdef SECONDARY_MEMORY_NEEDED /* If reload requires moving value through secondary memory, it will need one more insn at least. */ - if (this_alternative != NO_REGS + if (this_alternative != NO_REGS && REG_P (op) && (cl = get_reg_class (REGNO (op))) != NO_REGS && ((curr_static_id->operand[nop].type != OP_OUT && SECONDARY_MEMORY_NEEDED (cl, this_alternative, @@ -3012,7 +3012,7 @@ process_address_1 (int nop, rtx *before, rtx *after) code = -1; } } - + } } if (code < 0) @@ -3414,7 +3414,7 @@ curr_insn_transform (void) change_p = true; lra_update_dup (curr_id, i); } - + if (change_p) /* If we've changed the instruction then any alternative that we chose previously may no longer be valid. */ @@ -3707,7 +3707,8 @@ curr_insn_transform (void) assigment pass and the scratch pseudo will be spilled. Spilled scratch pseudos are transformed back to scratches at the LRA end. */ - && lra_former_scratch_operand_p (curr_insn, i)) + && lra_former_scratch_operand_p (curr_insn, i) + && lra_former_scratch_p (REGNO (op))) { int regno = REGNO (op); lra_change_class (regno, NO_REGS, " Change to", true); @@ -3716,6 +3717,8 @@ curr_insn_transform (void) spilled pseudo as there is only one such insn, the current one. */ reg_renumber[regno] = -1; + lra_assert (bitmap_single_bit_set_p + (&lra_reg_info[REGNO (op)].insn_bitmap)); } /* We can do an optional reload. If the pseudo got a hard reg, we might improve the code through inheritance. If @@ -4214,7 +4217,7 @@ lra_constraints (bool first_p) the equiv. We could update the equiv insns after transformations including an equiv insn deletion but it is not worthy as such cases are extremely - rare. */ + rare. */ || contains_deleted_insn_p (ira_reg_equiv[i].init_insns) /* If it is not a reverse equivalence, we check that a pseudo in rhs of the init insn is not dying in the @@ -4306,7 +4309,7 @@ lra_constraints (bool first_p) can not be changed. Such insns might be not in init_insns because we don't update equiv data during insn transformations. - + As an example, let suppose that a pseudo got hard register and on the 1st pass was not changed to equivalent constant. We generate an diff --git a/gcc-4.9/gcc/tree-ssa-loop-niter.c b/gcc-4.9/gcc/tree-ssa-loop-niter.c index cb9214fbb..db069e06c 100644 --- a/gcc-4.9/gcc/tree-ssa-loop-niter.c +++ b/gcc-4.9/gcc/tree-ssa-loop-niter.c @@ -3950,7 +3950,21 @@ loop_exits_before_overflow (tree base, tree step, if (!CONVERT_EXPR_P (e) || !operand_equal_p (e, unsigned_base, 0)) continue; e = TREE_OPERAND (e, 0); - gcc_assert (operand_equal_p (e, base, 0)); + /* It may still be possible to prove no overflow even if condition + "operand_equal_p (e, base, 0)" isn't satisfied here, like below + example: + + e : ssa_var ; unsigned long type + base : (int) ssa_var + unsigned_base : (unsigned int) ssa_var + + Unfortunately this is a rare case observed during GCC profiled + bootstrap. See PR66638 for more information. + + For now, we just skip the possibility. */ + if (!operand_equal_p (e, base, 0)) + continue; + if (tree_int_cst_sign_bit (step)) { code = LT_EXPR; |