This is an automated email from the git hooks/post-receive script.
unknown user pushed a commit to branch aoliva/pr64164 in repository gcc.
commit 3004886e489b18e67ad97660b2de6ed14d1b011c Author: Alexandre Oliva aoliva@redhat.com Date: Wed Jul 29 14:34:34 2015 -0300
incremental fixes
PR bootstrap/66978 * function.c (expand_function_start): Convert static chain to Pmode if needed. From H.J. Lu hongjiu.lu@intel.com. PR middle-end/66983 PR middle-end/67035 * cfgexpand.c (align_local_variable, add_stack_var): Support anonymous SSA names. (defer_stack_allocation): Likewise. Declare earlier. (expand_one_ssa_partition): Record alignment before expanding stack vars. Support deferred allocation. (set_rtl): Do no record deferred-allocation marker in SA.partition_to_pseudo. (expand_stack_vars): Adjust check for the marker in it. (adjust_one_expanded_partition_var): Skip deferred-alloc vars. PR middle-end/67034 * function.c (assign_parm_setup_reg): Copy BLKmode byref args to RTL assigned to their default partition. PR rtl-optimization/67000 * expr.c (read_complex_part): Export. * expr.h (read_complex_part): Declare. * function.c (split_complex_args): Use it. (assign_parms_unsplit_complex): Use the preexisting complex RTL if it matches the components. (assign_parm_setup_reg): Drop assert on from_expand mode. Adjust it to the promoted_mode. --- gcc/cfgexpand.c | 77 +++++++++++++++++++++++++++++++++++++++++---------------- gcc/expr.c | 2 +- gcc/expr.h | 1 + gcc/function.c | 63 ++++++++++++++++++++++++++++++++++------------ 4 files changed, 105 insertions(+), 38 deletions(-)
diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c index 0b19953..9577ad6d 100644 --- a/gcc/cfgexpand.c +++ b/gcc/cfgexpand.c @@ -97,6 +97,8 @@ gimple currently_expanding_gimple_stmt;
static rtx expand_debug_expr (tree);
+static bool defer_stack_allocation (tree, bool); + /* Return an expression tree corresponding to the RHS of GIMPLE statement STMT. */
@@ -253,7 +255,7 @@ set_rtl (tree t, rtx x) { if (SA.partition_to_pseudo[part]) gcc_assert (SA.partition_to_pseudo[part] == x); - else + else if (x != pc_rtx) SA.partition_to_pseudo[part] = x; } /* For the benefit of debug information at -O0 (where @@ -348,8 +350,15 @@ static bool has_short_buffer; static unsigned int align_local_variable (tree decl) { - unsigned int align = LOCAL_DECL_ALIGNMENT (decl); - DECL_ALIGN (decl) = align; + unsigned int align; + + if (TREE_CODE (decl) == SSA_NAME) + align = TYPE_ALIGN (TREE_TYPE (decl)); + else + { + align = LOCAL_DECL_ALIGNMENT (decl); + DECL_ALIGN (decl) = align; + } return align / BITS_PER_UNIT; }
@@ -415,12 +424,15 @@ add_stack_var (tree decl) decl_to_stack_part->put (decl, stack_vars_num);
v->decl = decl; - v->size = tree_to_uhwi (DECL_SIZE_UNIT (SSAVAR (decl))); + tree size = TREE_CODE (decl) == SSA_NAME + ? TYPE_SIZE_UNIT (TREE_TYPE (decl)) + : DECL_SIZE_UNIT (decl); + v->size = tree_to_uhwi (size); /* Ensure that all variables have size, so that &a != &b for any two variables that are simultaneously live. */ if (v->size == 0) v->size = 1; - v->alignb = align_local_variable (SSAVAR (decl)); + v->alignb = align_local_variable (decl); /* An alignment of zero can mightily confuse us later. */ gcc_assert (v->alignb != 0);
@@ -1051,9 +1063,9 @@ expand_stack_vars (bool (*pred) (size_t), struct stack_vars_d [...] /* Skip variables that have already had rtl assigned. See also add_stack_var where we perpetrate this pc_rtx hack. */ decl = stack_vars[i].decl; - if ((TREE_CODE (decl) == SSA_NAME - ? SA.partition_to_pseudo[var_to_partition (SA.map, decl)] - : DECL_RTL (decl)) != pc_rtx) + if (TREE_CODE (decl) == SSA_NAME + ? SA.partition_to_pseudo[var_to_partition (SA.map, decl)] != NULL_RTX + : DECL_RTL (decl) != pc_rtx) continue;
large_size += alignb - 1; @@ -1082,9 +1094,9 @@ expand_stack_vars (bool (*pred) (size_t), struct stack_vars_d [...] /* Skip variables that have already had rtl assigned. See also add_stack_var where we perpetrate this pc_rtx hack. */ decl = stack_vars[i].decl; - if ((TREE_CODE (decl) == SSA_NAME - ? SA.partition_to_pseudo[var_to_partition (SA.map, decl)] - : DECL_RTL (decl)) != pc_rtx) + if (TREE_CODE (decl) == SSA_NAME + ? SA.partition_to_pseudo[var_to_partition (SA.map, decl)] != NULL_RTX + : DECL_RTL (decl) != pc_rtx) continue;
/* Check the predicate to see whether this variable should be @@ -1290,12 +1302,6 @@ expand_one_ssa_partition (tree var) if (SA.partition_to_pseudo[part]) return;
- if (!use_register_for_decl (var)) - { - expand_one_stack_var_1 (var); - return; - } - unsigned int align = MINIMUM_ALIGNMENT (TREE_TYPE (var), TYPE_MODE (TREE_TYPE (var)), TYPE_ALIGN (TREE_TYPE (var))); @@ -1307,6 +1313,15 @@ expand_one_ssa_partition (tree var)
record_alignment_for_reg_var (align);
+ if (!use_register_for_decl (var)) + { + if (defer_stack_allocation (var, true)) + add_stack_var (var); + else + expand_one_stack_var_1 (var); + return; + } + machine_mode reg_mode = promote_ssa_mode (var, NULL);
rtx x = gen_reg_rtx (reg_mode); @@ -1331,6 +1346,13 @@ adjust_one_expanded_partition_var (tree var)
rtx x = SA.partition_to_pseudo[part];
+ if (!x) + { + /* This var will get a stack slot later. */ + gcc_assert (defer_stack_allocation (var, true)); + return; + } + set_rtl (var, x);
if (!REG_P (x)) @@ -1409,10 +1431,14 @@ expand_one_error_var (tree var) static bool defer_stack_allocation (tree var, bool toplevel) { + tree size_unit = TREE_CODE (var) == SSA_NAME + ? TYPE_SIZE_UNIT (TREE_TYPE (var)) + : DECL_SIZE_UNIT (var); + /* Whether the variable is small enough for immediate allocation not to be a problem with regard to the frame size. */ bool smallish - = ((HOST_WIDE_INT) tree_to_uhwi (DECL_SIZE_UNIT (var)) + = ((HOST_WIDE_INT) tree_to_uhwi (size_unit) < PARAM_VALUE (PARAM_MIN_SIZE_FOR_STACK_SHARING));
/* If stack protection is enabled, *all* stack variables must be deferred, @@ -1421,16 +1447,24 @@ defer_stack_allocation (tree var, bool toplevel) if (flag_stack_protect || ((flag_sanitize & SANITIZE_ADDRESS) && ASAN_STACK)) return true;
+ unsigned int align = TREE_CODE (var) == SSA_NAME + ? TYPE_ALIGN (TREE_TYPE (var)) + : DECL_ALIGN (var); + /* We handle "large" alignment via dynamic allocation. We want to handle this extra complication in only one place, so defer them. */ - if (DECL_ALIGN (var) > MAX_SUPPORTED_STACK_ALIGNMENT) + if (align > MAX_SUPPORTED_STACK_ALIGNMENT) return true;
+ bool ignored = TREE_CODE (var) == SSA_NAME + ? !SSAVAR (var) || DECL_IGNORED_P (SSA_NAME_VAR (var)) + : DECL_IGNORED_P (var); + /* When optimization is enabled, DECL_IGNORED_P variables originally scoped might be detached from their block and appear at toplevel when we reach here. We want to coalesce them with variables from other blocks when the immediate contribution to the frame size would be noticeable. */ - if (toplevel && optimize > 0 && DECL_IGNORED_P (var) && !smallish) + if (toplevel && optimize > 0 && ignored && !smallish) return true;
/* Variables declared in the outermost scope automatically conflict @@ -6135,7 +6169,8 @@ pass_expand::execute (function *fun) if (part == NO_PARTITION) continue;
- gcc_assert (SA.partition_to_pseudo[part]); + gcc_assert (SA.partition_to_pseudo[part] + || defer_stack_allocation (name, true));
/* If this decl was marked as living in multiple places, reset this now to NULL. */ diff --git a/gcc/expr.c b/gcc/expr.c index d601129..fc49f92 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -3022,7 +3022,7 @@ write_complex_part (rtx cplx, rtx val, bool imag_p) /* Extract one of the components of the complex value CPLX. Extract the real part if IMAG_P is false, and the imaginary part if it's true. */
-static rtx +rtx read_complex_part (rtx cplx, bool imag_p) { machine_mode cmode, imode; diff --git a/gcc/expr.h b/gcc/expr.h index 32d1707..a2c8e1d 100644 --- a/gcc/expr.h +++ b/gcc/expr.h @@ -210,6 +210,7 @@ extern rtx_insn *emit_move_insn_1 (rtx, rtx);
extern rtx_insn *emit_move_complex_push (machine_mode, rtx, rtx); extern rtx_insn *emit_move_complex_parts (rtx, rtx); +extern rtx read_complex_part (rtx, bool); extern void write_complex_part (rtx, rtx, bool); extern rtx emit_move_resolve_push (machine_mode, rtx);
diff --git a/gcc/function.c b/gcc/function.c index c3d00cd..53bd42b 100644 --- a/gcc/function.c +++ b/gcc/function.c @@ -2322,11 +2322,10 @@ split_complex_args (struct assign_parm_data_all *all, vec<t [...] if (currently_expanding_to_rtl) { rtx rtl = rtl_for_parm (all, cparm); - gcc_assert (!rtl || GET_CODE (rtl) == CONCAT); if (rtl) { - SET_DECL_RTL (p, XEXP (rtl, 0)); - SET_DECL_RTL (decl, XEXP (rtl, 1)); + SET_DECL_RTL (p, read_complex_part (rtl, false)); + SET_DECL_RTL (decl, read_complex_part (rtl, true));
DECL_CONTEXT (p) = cparm; DECL_CONTEXT (decl) = cparm; @@ -3104,10 +3103,11 @@ assign_parm_setup_reg (struct assign_parm_data_all *all, tr [...]
rtx from_expand = rtl_for_parm (all, parm);
- if (from_expand && !data->passed_pointer) + if (from_expand) { parmreg = from_expand; - gcc_assert (GET_MODE (parmreg) == promoted_nominal_mode); + if (GET_MODE (parmreg) != promoted_nominal_mode) + parmreg = gen_lowpart (promoted_nominal_mode, parmreg); } else { @@ -3118,7 +3118,7 @@ assign_parm_setup_reg (struct assign_parm_data_all *all, tree parm,
/* If this was an item that we received a pointer to, set DECL_RTL appropriately. */ - if (data->passed_pointer) + if (!from_expand && data->passed_pointer) { rtx x = gen_rtx_MEM (TYPE_MODE (TREE_TYPE (data->passed_type)), parmreg); set_mem_attributes (x, parm, 1); @@ -3139,7 +3139,8 @@ assign_parm_setup_reg (struct assign_parm_data_all *all, tree parm,
need_conversion = (data->nominal_mode != data->passed_mode || promoted_nominal_mode != data->promoted_mode); - moved = false; + gcc_assert (!(need_conversion && data->passed_pointer)); + moved = from_expand && data->passed_pointer;
if (need_conversion && GET_MODE_CLASS (data->nominal_mode) == MODE_INT @@ -3278,12 +3279,15 @@ assign_parm_setup_reg (struct assign_parm_data_all *all, tr [...] if (data->passed_pointer && (from_expand || TYPE_MODE (TREE_TYPE (parm)) != BLKmode)) { + rtx src = DECL_RTL (parm); + /* We can't use nominal_mode, because it will have been set to Pmode above. We must use the actual mode of the parm. */ if (from_expand) { - parmreg = from_expand; gcc_assert (GET_MODE (parmreg) == TYPE_MODE (TREE_TYPE (parm))); + src = gen_rtx_MEM (GET_MODE (parmreg), validated_mem); + set_mem_attributes (src, parm, 1); } else if (use_register_for_decl (parm)) { @@ -3302,14 +3306,14 @@ assign_parm_setup_reg (struct assign_parm_data_all *all, tr [...] set_mem_attributes (parmreg, parm, 1); }
- if (GET_MODE (parmreg) != GET_MODE (DECL_RTL (parm))) + if (GET_MODE (parmreg) != GET_MODE (src)) { - rtx tempreg = gen_reg_rtx (GET_MODE (DECL_RTL (parm))); + rtx tempreg = gen_reg_rtx (GET_MODE (src)); int unsigned_p = TYPE_UNSIGNED (TREE_TYPE (parm));
push_to_sequence2 (all->first_conversion_insn, all->last_conversion_insn); - emit_move_insn (tempreg, DECL_RTL (parm)); + emit_move_insn (tempreg, src); tempreg = convert_to_mode (GET_MODE (parmreg), tempreg, unsigned_p); emit_move_insn (parmreg, tempreg); all->first_conversion_insn = get_insns (); @@ -3318,8 +3322,21 @@ assign_parm_setup_reg (struct assign_parm_data_all *all, tree parm,
did_conversion = true; } + else if (GET_MODE (parmreg) == BLKmode) + { + push_to_sequence2 (all->first_conversion_insn, + all->last_conversion_insn); + gcc_assert (TREE_CODE (data->passed_type) == POINTER_TYPE); + gcc_assert (TREE_TYPE (data->passed_type) == TREE_TYPE (parm)); + emit_block_move (parmreg, src, + GEN_INT (int_size_in_bytes (TREE_TYPE (parm))), + BLOCK_OP_NORMAL);; + all->first_conversion_insn = get_insns (); + all->last_conversion_insn = get_last_insn (); + end_sequence (); + } else - emit_move_insn (parmreg, DECL_RTL (parm)); + emit_move_insn (parmreg, src);
SET_DECL_RTL (parm, parmreg);
@@ -3495,11 +3512,21 @@ assign_parms_unsplit_complex (struct assign_parm_data_all *all, imag = DECL_RTL (fnargs[i + 1]); if (inner != GET_MODE (real)) { - real = gen_lowpart_SUBREG (inner, real); - imag = gen_lowpart_SUBREG (inner, imag); + real = simplify_gen_subreg (inner, real, GET_MODE (real), + subreg_lowpart_offset + (inner, GET_MODE (real))); + imag = simplify_gen_subreg (inner, imag, GET_MODE (imag), + subreg_lowpart_offset + (inner, GET_MODE (imag))); }
- if (TREE_ADDRESSABLE (parm)) + if ((tmp = DECL_RTL_IF_SET (parm)) + && rtx_equal_p (real, + read_complex_part (tmp, false)) + && rtx_equal_p (imag, + read_complex_part (tmp, true))) + ; /* We have the right rtl in parm and tmp already. */ + else if (TREE_ADDRESSABLE (parm)) { rtx rmem, imem; HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (parm)); @@ -3645,7 +3672,7 @@ assign_bounds (vec<bounds_parm_data> &bndargs, assign_parm_setup_block (&all, pbdata->bounds_parm, &pbdata->parm_data); else if (pbdata->parm_data.passed_pointer - || use_register_for_decl (pbdata->bounds_parm)) + || use_register_for_parm_decl (&all, pbdata->bounds_parm)) assign_parm_setup_reg (&all, pbdata->bounds_parm, &pbdata->parm_data); else @@ -5207,6 +5234,10 @@ expand_function_start (tree subr) SET_DECL_RTL (parm, local); mark_reg_pointer (local, TYPE_ALIGN (TREE_TYPE (TREE_TYPE (parm))));
+ if (GET_MODE (local) != Pmode) + local = convert_to_mode (Pmode, local, + TYPE_UNSIGNED (TREE_TYPE (parm))); + insn = emit_move_insn (local, chain);
/* Mark the register as eliminable, similar to parameters. */