diff options
Diffstat (limited to 'gcc-4.8/gcc/function.c')
-rw-r--r-- | gcc-4.8/gcc/function.c | 58 |
1 files changed, 35 insertions, 23 deletions
diff --git a/gcc-4.8/gcc/function.c b/gcc-4.8/gcc/function.c index e673f21a5..a67167ab6 100644 --- a/gcc-4.8/gcc/function.c +++ b/gcc-4.8/gcc/function.c @@ -2507,6 +2507,7 @@ assign_parm_find_entry_rtl (struct assign_parm_data_all *all, } locate_and_pad_parm (data->promoted_mode, data->passed_type, in_regs, + all->reg_parm_stack_space, entry_parm ? data->partial : 0, current_function_decl, &all->stack_args_size, &data->locate); @@ -3485,11 +3486,7 @@ assign_parms (tree fndecl) /* Adjust function incoming argument size for alignment and minimum length. */ -#ifdef REG_PARM_STACK_SPACE - crtl->args.size = MAX (crtl->args.size, - REG_PARM_STACK_SPACE (fndecl)); -#endif - + crtl->args.size = MAX (crtl->args.size, all.reg_parm_stack_space); crtl->args.size = CEIL_ROUND (crtl->args.size, PARM_BOUNDARY / BITS_PER_UNIT); @@ -3693,6 +3690,9 @@ gimplify_parameters (void) IN_REGS is nonzero if the argument will be passed in registers. It will never be set if REG_PARM_STACK_SPACE is not defined. + REG_PARM_STACK_SPACE is the number of bytes of stack space reserved + for arguments which are passed in registers. + FNDECL is the function in which the argument was defined. There are two types of rounding that are done. The first, controlled by @@ -3713,19 +3713,16 @@ gimplify_parameters (void) void locate_and_pad_parm (enum machine_mode passed_mode, tree type, int in_regs, - int partial, tree fndecl ATTRIBUTE_UNUSED, + int reg_parm_stack_space, int partial, + tree fndecl ATTRIBUTE_UNUSED, struct args_size *initial_offset_ptr, struct locate_and_pad_arg_data *locate) { tree sizetree; enum direction where_pad; unsigned int boundary, round_boundary; - int reg_parm_stack_space = 0; int part_size_in_regs; -#ifdef REG_PARM_STACK_SPACE - reg_parm_stack_space = REG_PARM_STACK_SPACE (fndecl); - /* If we have found a stack parm before we reach the end of the area reserved for registers, skip that area. */ if (! in_regs) @@ -3743,7 +3740,6 @@ locate_and_pad_parm (enum machine_mode passed_mode, tree type, int in_regs, initial_offset_ptr->constant = reg_parm_stack_space; } } -#endif /* REG_PARM_STACK_SPACE */ part_size_in_regs = (reg_parm_stack_space == 0 ? partial : 0); @@ -3806,11 +3802,7 @@ locate_and_pad_parm (enum machine_mode passed_mode, tree type, int in_regs, locate->slot_offset.constant += part_size_in_regs; - if (!in_regs -#ifdef REG_PARM_STACK_SPACE - || REG_PARM_STACK_SPACE (fndecl) > 0 -#endif - ) + if (!in_regs || reg_parm_stack_space > 0) pad_to_arg_alignment (&locate->slot_offset, boundary, &locate->alignment_pad); @@ -3830,11 +3822,7 @@ locate_and_pad_parm (enum machine_mode passed_mode, tree type, int in_regs, pad_below (&locate->offset, passed_mode, sizetree); #else /* !ARGS_GROW_DOWNWARD */ - if (!in_regs -#ifdef REG_PARM_STACK_SPACE - || REG_PARM_STACK_SPACE (fndecl) > 0 -#endif - ) + if (!in_regs || reg_parm_stack_space > 0) pad_to_arg_alignment (initial_offset_ptr, boundary, &locate->alignment_pad); locate->slot_offset = *initial_offset_ptr; @@ -5093,6 +5081,7 @@ expand_function_end (void) amount. BLKmode results are handled using the group load/store machinery. */ if (TYPE_MODE (TREE_TYPE (decl_result)) != BLKmode + && REG_P (real_decl_rtl) && targetm.calls.return_in_msb (TREE_TYPE (decl_result))) { emit_move_insn (gen_rtx_REG (GET_MODE (decl_rtl), @@ -5509,9 +5498,12 @@ move_insn_for_shrink_wrap (basic_block bb, rtx insn, except for any part that overlaps SRC (next loop). */ bb_uses = &DF_LR_BB_INFO (bb)->use; bb_defs = &DF_LR_BB_INFO (bb)->def; + if (df_live) + { for (i = dregno; i < end_dregno; i++) { - if (REGNO_REG_SET_P (bb_uses, i) || REGNO_REG_SET_P (bb_defs, i)) + if (REGNO_REG_SET_P (bb_uses, i) || REGNO_REG_SET_P (bb_defs, i) + || REGNO_REG_SET_P (&DF_LIVE_BB_INFO (bb)->gen, i)) next_block = NULL; CLEAR_REGNO_REG_SET (live_out, i); CLEAR_REGNO_REG_SET (live_in, i); @@ -5521,11 +5513,31 @@ move_insn_for_shrink_wrap (basic_block bb, rtx insn, Either way, SRC is now live on entry. */ for (i = sregno; i < end_sregno; i++) { - if (REGNO_REG_SET_P (bb_defs, i)) + if (REGNO_REG_SET_P (bb_defs, i) + || REGNO_REG_SET_P (&DF_LIVE_BB_INFO (bb)->gen, i)) next_block = NULL; SET_REGNO_REG_SET (live_out, i); SET_REGNO_REG_SET (live_in, i); } + } + else + { + /* DF_LR_BB_INFO (bb)->def does not comprise the DF_REF_PARTIAL and + DF_REF_CONDITIONAL defs. So if DF_LIVE doesn't exist, i.e. + at -O1, just give up searching NEXT_BLOCK. */ + next_block = NULL; + for (i = dregno; i < end_dregno; i++) + { + CLEAR_REGNO_REG_SET (live_out, i); + CLEAR_REGNO_REG_SET (live_in, i); + } + + for (i = sregno; i < end_sregno; i++) + { + SET_REGNO_REG_SET (live_out, i); + SET_REGNO_REG_SET (live_in, i); + } + } /* If we don't need to add the move to BB, look for a single successor block. */ |