aboutsummaryrefslogtreecommitdiff
path: root/gcc/function.c
diff options
context:
space:
mode:
authorAlexandre Oliva <aoliva@redhat.com>2015-06-10 00:37:39 +0000
committerAlexandre Oliva <aoliva@gcc.gnu.org>2015-06-10 00:37:39 +0000
commit0f9f9784ad1bb59e89f03e5cb00ebc22f500c059 (patch)
tree44bd2d64a442165a5d4162e8caf3157b8f5557a6 /gcc/function.c
parenta79b6a3044aa97f8ba6b491ee1796f318c68285a (diff)
downloadgcc-0f9f9784ad1bb59e89f03e5cb00ebc22f500c059.zip
gcc-0f9f9784ad1bb59e89f03e5cb00ebc22f500c059.tar.gz
gcc-0f9f9784ad1bb59e89f03e5cb00ebc22f500c059.tar.bz2
Revert "[PR64164] Drop copyrename, use coalescible partition as base when optimizing."
This reverts commit c66acc7cedd89bfd22124caec44b8427c9082dac. Conflicts: gcc/ChangeLog gcc/testsuite/ChangeLog From-SVN: r224310
Diffstat (limited to 'gcc/function.c')
-rw-r--r--gcc/function.c226
1 files changed, 45 insertions, 181 deletions
diff --git a/gcc/function.c b/gcc/function.c
index 8bcc352..8baaed7 100644
--- a/gcc/function.c
+++ b/gcc/function.c
@@ -77,7 +77,6 @@ along with GCC; see the file COPYING3. If not see
#include "cfganal.h"
#include "cfgbuild.h"
#include "cfgcleanup.h"
-#include "cfgexpand.h"
#include "basic-block.h"
#include "df.h"
#include "params.h"
@@ -2112,30 +2111,6 @@ aggregate_value_p (const_tree exp, const_tree fntype)
bool
use_register_for_decl (const_tree decl)
{
- if (TREE_CODE (decl) == SSA_NAME)
- {
- /* We often try to use the SSA_NAME, instead of its underlying
- decl, to get type information and guide decisions, to avoid
- differences of behavior between anonymous and named
- variables, but in this one case we have to go for the actual
- variable if there is one. The main reason is that, at least
- at -O0, we want to place user variables on the stack, but we
- don't mind using pseudos for anonymous or ignored temps.
- Should we take the SSA_NAME, we'd conclude all SSA_NAMEs
- should go in pseudos, whereas their corresponding variables
- might have to go on the stack. So, disregarding the decl
- here would negatively impact debug info at -O0, enable
- coalescing between SSA_NAMEs that ought to get different
- stack/pseudo assignments, and get the incoming argument
- processing thoroughly confused by PARM_DECLs expected to live
- in stack slots but assigned to pseudos. */
- if (!SSA_NAME_VAR (decl))
- return TYPE_MODE (TREE_TYPE (decl)) != BLKmode
- && !(flag_float_store && FLOAT_TYPE_P (TREE_TYPE (decl)));
-
- decl = SSA_NAME_VAR (decl);
- }
-
if (!targetm.calls.allocate_stack_slots_for_args ())
return true;
@@ -2819,88 +2794,23 @@ assign_parm_remove_parallels (struct assign_parm_data_one *data)
data->entry_parm = entry_parm;
}
-/* Wrapper for use_register_for_decl, that special-cases the
- .result_ptr as the function's RESULT_DECL when the RESULT_DECL is
- passed by reference. */
-
-static bool
-use_register_for_parm_decl (struct assign_parm_data_all *all, tree parm)
-{
- if (parm == all->function_result_decl)
- {
- tree result = DECL_RESULT (current_function_decl);
-
- if (DECL_BY_REFERENCE (result))
- parm = result;
- }
-
- return use_register_for_decl (parm);
-}
-
-/* Wrapper for get_rtl_for_parm_ssa_default_def, that special-cases
- the .result_ptr as the function's RESULT_DECL when the RESULT_DECL
- is passed by reference. */
-
-static rtx
-rtl_for_parm (struct assign_parm_data_all *all, tree parm)
-{
- if (parm == all->function_result_decl)
- {
- tree result = DECL_RESULT (current_function_decl);
-
- if (!DECL_BY_REFERENCE (result))
- return NULL_RTX;
-
- parm = result;
- }
-
- return get_rtl_for_parm_ssa_default_def (parm);
-}
-
-/* Reset the location of PARM_DECLs and RESULT_DECLs that had
- SSA_NAMEs in multiple partitions, so that assign_parms will choose
- the default def, if it exists, or create new RTL to hold the unused
- entry value. If we are coalescing across variables, we want to
- reset the location too, because a parm without a default def
- (incoming value unused) might be coalesced with one with a default
- def, and then assign_parms would copy both incoming values to the
- same location, which might cause the wrong value to survive. */
-static void
-maybe_reset_rtl_for_parm (tree parm)
-{
- gcc_assert (TREE_CODE (parm) == PARM_DECL
- || TREE_CODE (parm) == RESULT_DECL);
- if ((flag_tree_coalesce_vars
- || (DECL_RTL_SET_P (parm) && DECL_RTL (parm) == pc_rtx))
- && is_gimple_reg (parm))
- SET_DECL_RTL (parm, NULL_RTX);
-}
-
/* A subroutine of assign_parms. Adjust DATA->STACK_RTL such that it's
always valid and properly aligned. */
static void
-assign_parm_adjust_stack_rtl (struct assign_parm_data_all *all, tree parm,
- struct assign_parm_data_one *data)
+assign_parm_adjust_stack_rtl (struct assign_parm_data_one *data)
{
rtx stack_parm = data->stack_parm;
- /* If out-of-SSA assigned RTL to the parm default def, make sure we
- don't use what we might have computed before. */
- rtx ssa_assigned = rtl_for_parm (all, parm);
- if (ssa_assigned)
- stack_parm = NULL;
-
/* If we can't trust the parm stack slot to be aligned enough for its
ultimate type, don't use that slot after entry. We'll make another
stack slot, if we need one. */
- else if (stack_parm
- && ((STRICT_ALIGNMENT
- && (GET_MODE_ALIGNMENT (data->nominal_mode)
- > MEM_ALIGN (stack_parm)))
- || (data->nominal_type
- && TYPE_ALIGN (data->nominal_type) > MEM_ALIGN (stack_parm)
- && MEM_ALIGN (stack_parm) < PREFERRED_STACK_BOUNDARY)))
+ if (stack_parm
+ && ((STRICT_ALIGNMENT
+ && GET_MODE_ALIGNMENT (data->nominal_mode) > MEM_ALIGN (stack_parm))
+ || (data->nominal_type
+ && TYPE_ALIGN (data->nominal_type) > MEM_ALIGN (stack_parm)
+ && MEM_ALIGN (stack_parm) < PREFERRED_STACK_BOUNDARY)))
stack_parm = NULL;
/* If parm was passed in memory, and we need to convert it on entry,
@@ -2962,16 +2872,11 @@ assign_parm_setup_block (struct assign_parm_data_all *all,
size = int_size_in_bytes (data->passed_type);
size_stored = CEIL_ROUND (size, UNITS_PER_WORD);
-
if (stack_parm == 0)
{
DECL_ALIGN (parm) = MAX (DECL_ALIGN (parm), BITS_PER_WORD);
- stack_parm = rtl_for_parm (all, parm);
- if (!stack_parm)
- stack_parm = assign_stack_local (BLKmode, size_stored,
- DECL_ALIGN (parm));
- else
- stack_parm = copy_rtx (stack_parm);
+ stack_parm = assign_stack_local (BLKmode, size_stored,
+ DECL_ALIGN (parm));
if (GET_MODE_SIZE (GET_MODE (entry_parm)) == size)
PUT_MODE (stack_parm, GET_MODE (entry_parm));
set_mem_attributes (stack_parm, parm, 1);
@@ -3112,19 +3017,10 @@ assign_parm_setup_reg (struct assign_parm_data_all *all, tree parm,
= promote_function_mode (data->nominal_type, data->nominal_mode, &unsignedp,
TREE_TYPE (current_function_decl), 2);
- rtx from_expand = rtl_for_parm (all, parm);
+ parmreg = gen_reg_rtx (promoted_nominal_mode);
- if (from_expand && !data->passed_pointer)
- {
- parmreg = from_expand;
- gcc_assert (GET_MODE (parmreg) == promoted_nominal_mode);
- }
- else
- {
- parmreg = gen_reg_rtx (promoted_nominal_mode);
- if (!DECL_ARTIFICIAL (parm))
- mark_user_reg (parmreg);
- }
+ if (!DECL_ARTIFICIAL (parm))
+ mark_user_reg (parmreg);
/* If this was an item that we received a pointer to,
set DECL_RTL appropriately. */
@@ -3143,8 +3039,6 @@ assign_parm_setup_reg (struct assign_parm_data_all *all, tree parm,
assign_parm_find_data_types and expand_expr_real_1. */
equiv_stack_parm = data->stack_parm;
- if (!equiv_stack_parm)
- equiv_stack_parm = data->entry_parm;
validated_mem = validize_mem (copy_rtx (data->entry_parm));
need_conversion = (data->nominal_mode != data->passed_mode
@@ -3285,17 +3179,11 @@ assign_parm_setup_reg (struct assign_parm_data_all *all, tree parm,
/* If we were passed a pointer but the actual value can safely live
in a register, retrieve it and use it directly. */
- if (data->passed_pointer
- && (from_expand || TYPE_MODE (TREE_TYPE (parm)) != BLKmode))
+ if (data->passed_pointer && TYPE_MODE (TREE_TYPE (parm)) != BLKmode)
{
/* 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)));
- }
- else if (use_register_for_decl (parm))
+ if (use_register_for_decl (parm))
{
parmreg = gen_reg_rtx (TYPE_MODE (TREE_TYPE (parm)));
mark_user_reg (parmreg);
@@ -3335,7 +3223,7 @@ assign_parm_setup_reg (struct assign_parm_data_all *all, tree parm,
/* STACK_PARM is the pointer, not the parm, and PARMREG is
now the parm. */
- data->stack_parm = equiv_stack_parm = NULL;
+ data->stack_parm = NULL;
}
/* Mark the register as eliminable if we did no conversion and it was
@@ -3345,11 +3233,11 @@ assign_parm_setup_reg (struct assign_parm_data_all *all, tree parm,
make here would screw up life analysis for it. */
if (data->nominal_mode == data->passed_mode
&& !did_conversion
- && equiv_stack_parm != 0
- && MEM_P (equiv_stack_parm)
+ && data->stack_parm != 0
+ && MEM_P (data->stack_parm)
&& data->locate.offset.var == 0
&& reg_mentioned_p (virtual_incoming_args_rtx,
- XEXP (equiv_stack_parm, 0)))
+ XEXP (data->stack_parm, 0)))
{
rtx_insn *linsn = get_last_insn ();
rtx_insn *sinsn;
@@ -3362,8 +3250,8 @@ assign_parm_setup_reg (struct assign_parm_data_all *all, tree parm,
= GET_MODE_INNER (GET_MODE (parmreg));
int regnor = REGNO (XEXP (parmreg, 0));
int regnoi = REGNO (XEXP (parmreg, 1));
- rtx stackr = adjust_address_nv (equiv_stack_parm, submode, 0);
- rtx stacki = adjust_address_nv (equiv_stack_parm, submode,
+ rtx stackr = adjust_address_nv (data->stack_parm, submode, 0);
+ rtx stacki = adjust_address_nv (data->stack_parm, submode,
GET_MODE_SIZE (submode));
/* Scan backwards for the set of the real and
@@ -3436,13 +3324,6 @@ assign_parm_setup_stack (struct assign_parm_data_all *all, tree parm,
if (data->stack_parm == 0)
{
- rtx x = data->stack_parm = rtl_for_parm (all, parm);
- if (x)
- gcc_assert (GET_MODE (x) == GET_MODE (data->entry_parm));
- }
-
- if (data->stack_parm == 0)
- {
int align = STACK_SLOT_ALIGNMENT (data->passed_type,
GET_MODE (data->entry_parm),
TYPE_ALIGN (data->passed_type));
@@ -3701,8 +3582,6 @@ assign_parms (tree fndecl)
DECL_INCOMING_RTL (parm) = DECL_RTL (parm);
continue;
}
- else
- maybe_reset_rtl_for_parm (parm);
/* Estimate stack alignment from parameter alignment. */
if (SUPPORTS_STACK_ALIGNMENT)
@@ -3752,9 +3631,7 @@ assign_parms (tree fndecl)
else
set_decl_incoming_rtl (parm, data.entry_parm, false);
- assign_parm_adjust_stack_rtl (&all, parm, &data);
-
- /* Bounds should be loaded in the particular order to
+ /* Boudns should be loaded in the particular order to
have registers allocated correctly. Collect info about
input bounds and load them later. */
if (POINTER_BOUNDS_TYPE_P (data.passed_type))
@@ -3771,10 +3648,11 @@ assign_parms (tree fndecl)
}
else
{
+ assign_parm_adjust_stack_rtl (&data);
+
if (assign_parm_setup_block_p (&data))
assign_parm_setup_block (&all, parm, &data);
- else if (data.passed_pointer
- || use_register_for_parm_decl (&all, parm))
+ else if (data.passed_pointer || use_register_for_decl (parm))
assign_parm_setup_reg (&all, parm, &data);
else
assign_parm_setup_stack (&all, parm, &data);
@@ -5116,9 +4994,7 @@ expand_function_start (tree subr)
before any library calls that assign parms might generate. */
/* Decide whether to return the value in memory or in a register. */
- tree res = DECL_RESULT (subr);
- maybe_reset_rtl_for_parm (res);
- if (aggregate_value_p (res, subr))
+ if (aggregate_value_p (DECL_RESULT (subr), subr))
{
/* Returning something that won't go in a register. */
rtx value_address = 0;
@@ -5126,7 +5002,7 @@ expand_function_start (tree subr)
#ifdef PCC_STATIC_STRUCT_RETURN
if (cfun->returns_pcc_struct)
{
- int size = int_size_in_bytes (TREE_TYPE (res));
+ int size = int_size_in_bytes (TREE_TYPE (DECL_RESULT (subr)));
value_address = assemble_static_space (size);
}
else
@@ -5138,45 +5014,36 @@ expand_function_start (tree subr)
it. */
if (sv)
{
- if (DECL_BY_REFERENCE (res))
- value_address = get_rtl_for_parm_ssa_default_def (res);
- if (!value_address)
- value_address = gen_reg_rtx (Pmode);
+ value_address = gen_reg_rtx (Pmode);
emit_move_insn (value_address, sv);
}
}
if (value_address)
{
rtx x = value_address;
- if (!DECL_BY_REFERENCE (res))
+ if (!DECL_BY_REFERENCE (DECL_RESULT (subr)))
{
- x = get_rtl_for_parm_ssa_default_def (res);
- if (!x)
- {
- x = gen_rtx_MEM (DECL_MODE (res), value_address);
- set_mem_attributes (x, res, 1);
- }
+ x = gen_rtx_MEM (DECL_MODE (DECL_RESULT (subr)), x);
+ set_mem_attributes (x, DECL_RESULT (subr), 1);
}
- SET_DECL_RTL (res, x);
+ SET_DECL_RTL (DECL_RESULT (subr), x);
}
}
- else if (DECL_MODE (res) == VOIDmode)
+ else if (DECL_MODE (DECL_RESULT (subr)) == VOIDmode)
/* If return mode is void, this decl rtl should not be used. */
- SET_DECL_RTL (res, NULL_RTX);
+ SET_DECL_RTL (DECL_RESULT (subr), NULL_RTX);
else
{
/* Compute the return values into a pseudo reg, which we will copy
into the true return register after the cleanups are done. */
- tree return_type = TREE_TYPE (res);
- rtx x = get_rtl_for_parm_ssa_default_def (res);
- if (x)
- /* Use it. */;
- else if (TYPE_MODE (return_type) != BLKmode
- && targetm.calls.return_in_msb (return_type))
+ tree return_type = TREE_TYPE (DECL_RESULT (subr));
+ if (TYPE_MODE (return_type) != BLKmode
+ && targetm.calls.return_in_msb (return_type))
/* expand_function_end will insert the appropriate padding in
this case. Use the return value's natural (unpadded) mode
within the function proper. */
- x = gen_reg_rtx (TYPE_MODE (return_type));
+ SET_DECL_RTL (DECL_RESULT (subr),
+ gen_reg_rtx (TYPE_MODE (return_type)));
else
{
/* In order to figure out what mode to use for the pseudo, we
@@ -5187,26 +5054,25 @@ expand_function_start (tree subr)
/* Structures that are returned in registers are not
aggregate_value_p, so we may see a PARALLEL or a REG. */
if (REG_P (hard_reg))
- x = gen_reg_rtx (GET_MODE (hard_reg));
+ SET_DECL_RTL (DECL_RESULT (subr),
+ gen_reg_rtx (GET_MODE (hard_reg)));
else
{
gcc_assert (GET_CODE (hard_reg) == PARALLEL);
- x = gen_group_rtx (hard_reg);
+ SET_DECL_RTL (DECL_RESULT (subr), gen_group_rtx (hard_reg));
}
}
- SET_DECL_RTL (res, x);
-
/* Set DECL_REGISTER flag so that expand_function_end will copy the
result to the real return register(s). */
- DECL_REGISTER (res) = 1;
+ DECL_REGISTER (DECL_RESULT (subr)) = 1;
if (chkp_function_instrumented_p (current_function_decl))
{
- tree return_type = TREE_TYPE (res);
+ tree return_type = TREE_TYPE (DECL_RESULT (subr));
rtx bounds = targetm.calls.chkp_function_value_bounds (return_type,
subr, 1);
- SET_DECL_BOUNDS_RTL (res, bounds);
+ SET_DECL_BOUNDS_RTL (DECL_RESULT (subr), bounds);
}
}
@@ -5221,9 +5087,7 @@ expand_function_start (tree subr)
rtx local, chain;
rtx_insn *insn;
- local = get_rtl_for_parm_ssa_default_def (parm);
- if (!local)
- local = gen_reg_rtx (Pmode);
+ local = gen_reg_rtx (Pmode);
chain = targetm.calls.static_chain (current_function_decl, true);
set_decl_incoming_rtl (parm, chain, false);