expr.c (store_field): Remove TYPE parameter.
* expr.c (store_field): Remove TYPE parameter. Remove block of code dealing with BLKmode in registers. Reimplement this support using pseudo-registers and bit-field techniques. (store_constructor_field): Remove TYPE parameter and adjust calls to store_field. (expand_assignment): Adjust calls to store_field. Add comment. (store_expr): Add comment. (store_constructor): Adjust calls to store_constructor_field. (expand_expr_real_2): Adjust call to store_field. From-SVN: r193391
This commit is contained in:
parent
35b07bb39e
commit
3467ad5ce6
2 changed files with 53 additions and 83 deletions
|
@ -1,3 +1,15 @@
|
|||
2012-11-10 Eric Botcazou <ebotcazou@adacore.com>
|
||||
|
||||
* expr.c (store_field): Remove TYPE parameter. Remove block of code
|
||||
dealing with BLKmode in registers. Reimplement this support using
|
||||
pseudo-registers and bit-field techniques.
|
||||
(store_constructor_field): Remove TYPE parameter and adjust calls to
|
||||
store_field.
|
||||
(expand_assignment): Adjust calls to store_field. Add comment.
|
||||
(store_expr): Add comment.
|
||||
(store_constructor): Adjust calls to store_constructor_field.
|
||||
(expand_expr_real_2): Adjust call to store_field.
|
||||
|
||||
2012-11-10 Vladimir Makarov <vmakarov@redhat.com>
|
||||
Uros Bizjak <ubizjak@gmail.com>
|
||||
|
||||
|
|
124
gcc/expr.c
124
gcc/expr.c
|
@ -137,12 +137,11 @@ static rtx compress_float_constant (rtx, rtx);
|
|||
static rtx get_subtarget (rtx);
|
||||
static void store_constructor_field (rtx, unsigned HOST_WIDE_INT,
|
||||
HOST_WIDE_INT, enum machine_mode,
|
||||
tree, tree, int, alias_set_type);
|
||||
tree, int, alias_set_type);
|
||||
static void store_constructor (tree, rtx, int, HOST_WIDE_INT);
|
||||
static rtx store_field (rtx, HOST_WIDE_INT, HOST_WIDE_INT,
|
||||
unsigned HOST_WIDE_INT, unsigned HOST_WIDE_INT,
|
||||
enum machine_mode,
|
||||
tree, tree, alias_set_type, bool);
|
||||
enum machine_mode, tree, alias_set_type, bool);
|
||||
|
||||
static unsigned HOST_WIDE_INT highest_pow2_factor_for_target (const_tree, const_tree);
|
||||
|
||||
|
@ -4772,15 +4771,14 @@ expand_assignment (tree to, tree from, bool nontemporal)
|
|||
else if (bitpos + bitsize <= mode_bitsize / 2)
|
||||
result = store_field (XEXP (to_rtx, 0), bitsize, bitpos,
|
||||
bitregion_start, bitregion_end,
|
||||
mode1, from, TREE_TYPE (tem),
|
||||
mode1, from,
|
||||
get_alias_set (to), nontemporal);
|
||||
else if (bitpos >= mode_bitsize / 2)
|
||||
result = store_field (XEXP (to_rtx, 1), bitsize,
|
||||
bitpos - mode_bitsize / 2,
|
||||
bitregion_start, bitregion_end,
|
||||
mode1, from,
|
||||
TREE_TYPE (tem), get_alias_set (to),
|
||||
nontemporal);
|
||||
get_alias_set (to), nontemporal);
|
||||
else if (bitpos == 0 && bitsize == mode_bitsize)
|
||||
{
|
||||
rtx from_rtx;
|
||||
|
@ -4801,8 +4799,7 @@ expand_assignment (tree to, tree from, bool nontemporal)
|
|||
result = store_field (temp, bitsize, bitpos,
|
||||
bitregion_start, bitregion_end,
|
||||
mode1, from,
|
||||
TREE_TYPE (tem), get_alias_set (to),
|
||||
nontemporal);
|
||||
get_alias_set (to), nontemporal);
|
||||
emit_move_insn (XEXP (to_rtx, 0), read_complex_part (temp, false));
|
||||
emit_move_insn (XEXP (to_rtx, 1), read_complex_part (temp, true));
|
||||
}
|
||||
|
@ -4834,8 +4831,7 @@ expand_assignment (tree to, tree from, bool nontemporal)
|
|||
result = store_field (to_rtx, bitsize, bitpos,
|
||||
bitregion_start, bitregion_end,
|
||||
mode1, from,
|
||||
TREE_TYPE (tem), get_alias_set (to),
|
||||
nontemporal);
|
||||
get_alias_set (to), nontemporal);
|
||||
}
|
||||
|
||||
if (misalignp)
|
||||
|
@ -4896,6 +4892,7 @@ expand_assignment (tree to, tree from, bool nontemporal)
|
|||
int_size_in_bytes (TREE_TYPE (from)));
|
||||
else if (GET_MODE (to_rtx) == BLKmode)
|
||||
{
|
||||
/* Handle calls that return BLKmode values in registers. */
|
||||
if (REG_P (value))
|
||||
copy_blkmode_from_reg (to_rtx, value, TREE_TYPE (from));
|
||||
else
|
||||
|
@ -5246,6 +5243,7 @@ store_expr (tree exp, rtx target, int call_param_p, bool nontemporal)
|
|||
{
|
||||
if (GET_MODE (target) == BLKmode)
|
||||
{
|
||||
/* Handle calls that return BLKmode values in registers. */
|
||||
if (REG_P (temp) && TREE_CODE (exp) == CALL_EXPR)
|
||||
copy_blkmode_from_reg (target, temp, TREE_TYPE (exp));
|
||||
else
|
||||
|
@ -5680,7 +5678,6 @@ all_zeros_p (const_tree exp)
|
|||
|
||||
/* Helper function for store_constructor.
|
||||
TARGET, BITSIZE, BITPOS, MODE, EXP are as for store_field.
|
||||
TYPE is the type of the CONSTRUCTOR, not the element type.
|
||||
CLEARED is as for store_constructor.
|
||||
ALIAS_SET is the alias set to use for any stores.
|
||||
|
||||
|
@ -5692,8 +5689,7 @@ all_zeros_p (const_tree exp)
|
|||
static void
|
||||
store_constructor_field (rtx target, unsigned HOST_WIDE_INT bitsize,
|
||||
HOST_WIDE_INT bitpos, enum machine_mode mode,
|
||||
tree exp, tree type, int cleared,
|
||||
alias_set_type alias_set)
|
||||
tree exp, int cleared, alias_set_type alias_set)
|
||||
{
|
||||
if (TREE_CODE (exp) == CONSTRUCTOR
|
||||
/* We can only call store_constructor recursively if the size and
|
||||
|
@ -5725,8 +5721,7 @@ store_constructor_field (rtx target, unsigned HOST_WIDE_INT bitsize,
|
|||
store_constructor (exp, target, cleared, bitsize / BITS_PER_UNIT);
|
||||
}
|
||||
else
|
||||
store_field (target, bitsize, bitpos, 0, 0, mode, exp, type, alias_set,
|
||||
false);
|
||||
store_field (target, bitsize, bitpos, 0, 0, mode, exp, alias_set, false);
|
||||
}
|
||||
|
||||
/* Store the value of constructor EXP into the rtx TARGET.
|
||||
|
@ -5897,7 +5892,7 @@ store_constructor (tree exp, rtx target, int cleared, HOST_WIDE_INT size)
|
|||
}
|
||||
|
||||
store_constructor_field (to_rtx, bitsize, bitpos, mode,
|
||||
value, type, cleared,
|
||||
value, cleared,
|
||||
get_alias_set (TREE_TYPE (field)));
|
||||
}
|
||||
break;
|
||||
|
@ -6052,7 +6047,7 @@ store_constructor (tree exp, rtx target, int cleared, HOST_WIDE_INT size)
|
|||
}
|
||||
|
||||
store_constructor_field
|
||||
(target, bitsize, bitpos, mode, value, type, cleared,
|
||||
(target, bitsize, bitpos, mode, value, cleared,
|
||||
get_alias_set (elttype));
|
||||
}
|
||||
}
|
||||
|
@ -6156,7 +6151,7 @@ store_constructor (tree exp, rtx target, int cleared, HOST_WIDE_INT size)
|
|||
MEM_KEEP_ALIAS_SET_P (target) = 1;
|
||||
}
|
||||
store_constructor_field (target, bitsize, bitpos, mode, value,
|
||||
type, cleared, get_alias_set (elttype));
|
||||
cleared, get_alias_set (elttype));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -6276,9 +6271,8 @@ store_constructor (tree exp, rtx target, int cleared, HOST_WIDE_INT size)
|
|||
? TYPE_MODE (TREE_TYPE (value))
|
||||
: eltmode;
|
||||
bitpos = eltpos * elt_size;
|
||||
store_constructor_field (target, bitsize, bitpos,
|
||||
value_mode, value, type,
|
||||
cleared, alias);
|
||||
store_constructor_field (target, bitsize, bitpos, value_mode,
|
||||
value, cleared, alias);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6307,8 +6301,6 @@ store_constructor (tree exp, rtx target, int cleared, HOST_WIDE_INT size)
|
|||
Always return const0_rtx unless we have something particular to
|
||||
return.
|
||||
|
||||
TYPE is the type of the underlying object,
|
||||
|
||||
ALIAS_SET is the alias set for the destination. This value will
|
||||
(in general) be different from that for TARGET, since TARGET is a
|
||||
reference to the containing structure.
|
||||
|
@ -6319,7 +6311,7 @@ static rtx
|
|||
store_field (rtx target, HOST_WIDE_INT bitsize, HOST_WIDE_INT bitpos,
|
||||
unsigned HOST_WIDE_INT bitregion_start,
|
||||
unsigned HOST_WIDE_INT bitregion_end,
|
||||
enum machine_mode mode, tree exp, tree type,
|
||||
enum machine_mode mode, tree exp,
|
||||
alias_set_type alias_set, bool nontemporal)
|
||||
{
|
||||
if (TREE_CODE (exp) == ERROR_MARK)
|
||||
|
@ -6330,38 +6322,6 @@ store_field (rtx target, HOST_WIDE_INT bitsize, HOST_WIDE_INT bitpos,
|
|||
if (bitsize == 0)
|
||||
return expand_expr (exp, const0_rtx, VOIDmode, EXPAND_NORMAL);
|
||||
|
||||
/* If we are storing into an unaligned field of an aligned union that is
|
||||
in a register, we may have the mode of TARGET being an integer mode but
|
||||
MODE == BLKmode. In that case, get an aligned object whose size and
|
||||
alignment are the same as TARGET and store TARGET into it (we can avoid
|
||||
the store if the field being stored is the entire width of TARGET). Then
|
||||
call ourselves recursively to store the field into a BLKmode version of
|
||||
that object. Finally, load from the object into TARGET. This is not
|
||||
very efficient in general, but should only be slightly more expensive
|
||||
than the otherwise-required unaligned accesses. Perhaps this can be
|
||||
cleaned up later. It's tempting to make OBJECT readonly, but it's set
|
||||
twice, once with emit_move_insn and once via store_field. */
|
||||
|
||||
if (mode == BLKmode
|
||||
&& (REG_P (target) || GET_CODE (target) == SUBREG)
|
||||
&& TREE_CODE (exp) != CALL_EXPR)
|
||||
{
|
||||
rtx object = assign_temp (type, 1, 1);
|
||||
rtx blk_object = adjust_address (object, BLKmode, 0);
|
||||
|
||||
if (bitsize != (HOST_WIDE_INT) GET_MODE_BITSIZE (GET_MODE (target)))
|
||||
emit_move_insn (object, target);
|
||||
|
||||
store_field (blk_object, bitsize, bitpos,
|
||||
bitregion_start, bitregion_end,
|
||||
mode, exp, type, MEM_ALIAS_SET (blk_object), nontemporal);
|
||||
|
||||
emit_move_insn (target, object);
|
||||
|
||||
/* We want to return the BLKmode version of the data. */
|
||||
return blk_object;
|
||||
}
|
||||
|
||||
if (GET_CODE (target) == CONCAT)
|
||||
{
|
||||
/* We're storing into a struct containing a single __complex. */
|
||||
|
@ -6472,35 +6432,34 @@ store_field (rtx target, HOST_WIDE_INT bitsize, HOST_WIDE_INT bitpos,
|
|||
The Irix 6 ABI has examples of this. */
|
||||
if (GET_CODE (temp) == PARALLEL)
|
||||
{
|
||||
HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (exp));
|
||||
rtx temp_target;
|
||||
|
||||
/* We are not supposed to have a true bitfield in this case. */
|
||||
gcc_assert (bitsize == GET_MODE_BITSIZE (mode));
|
||||
|
||||
/* If we don't store at bit 0, we need an intermediate pseudo
|
||||
since emit_group_store only stores at bit 0. */
|
||||
if (bitpos != 0)
|
||||
temp_target = gen_reg_rtx (mode);
|
||||
else
|
||||
temp_target = target;
|
||||
|
||||
emit_group_store (temp_target, temp, TREE_TYPE (exp),
|
||||
int_size_in_bytes (TREE_TYPE (exp)));
|
||||
|
||||
if (temp_target == target)
|
||||
return const0_rtx;
|
||||
|
||||
if (mode == BLKmode)
|
||||
mode = smallest_mode_for_size (size * BITS_PER_UNIT, MODE_INT);
|
||||
temp_target = gen_reg_rtx (mode);
|
||||
emit_group_store (temp_target, temp, TREE_TYPE (exp), size);
|
||||
temp = temp_target;
|
||||
}
|
||||
|
||||
/* Handle calls that return BLKmode values in registers. */
|
||||
else if (mode == BLKmode
|
||||
&& REG_P (temp)
|
||||
&& TREE_CODE (exp) == CALL_EXPR)
|
||||
else if (mode == BLKmode)
|
||||
{
|
||||
rtx temp_target = gen_reg_rtx (GET_MODE (temp));
|
||||
copy_blkmode_from_reg (temp_target, temp, TREE_TYPE (exp));
|
||||
temp = temp_target;
|
||||
/* Handle calls that return BLKmode values in registers. */
|
||||
if (REG_P (temp) && TREE_CODE (exp) == CALL_EXPR)
|
||||
{
|
||||
rtx temp_target = gen_reg_rtx (GET_MODE (temp));
|
||||
copy_blkmode_from_reg (temp_target, temp, TREE_TYPE (exp));
|
||||
temp = temp_target;
|
||||
}
|
||||
else
|
||||
{
|
||||
HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (exp));
|
||||
rtx temp_target;
|
||||
mode = smallest_mode_for_size (size * BITS_PER_UNIT, MODE_INT);
|
||||
temp_target = gen_reg_rtx (mode);
|
||||
temp_target
|
||||
= extract_bit_field (temp, size * BITS_PER_UNIT, 0, 1,
|
||||
false, temp_target, mode, mode);
|
||||
temp = temp_target;
|
||||
}
|
||||
}
|
||||
|
||||
/* Store the value in the bitfield. */
|
||||
|
@ -8059,8 +8018,7 @@ expand_expr_real_2 (sepops ops, rtx target, enum machine_mode tmode,
|
|||
(treeop0))
|
||||
* BITS_PER_UNIT),
|
||||
(HOST_WIDE_INT) GET_MODE_BITSIZE (mode)),
|
||||
0, 0, 0, TYPE_MODE (valtype), treeop0,
|
||||
type, 0, false);
|
||||
0, 0, 0, TYPE_MODE (valtype), treeop0, 0, false);
|
||||
}
|
||||
|
||||
/* Return the entire union. */
|
||||
|
|
Loading…
Add table
Reference in a new issue