expr.c (store_expr): When copying string constant into array...

* expr.c (store_expr): When copying string constant into array,
	use functions that update memrefs instead of computations on
	addresses to better track MEMs.  Also properly handle 32/64 pointers.
	(expand_expr): Use TARGET even if not reg for multi-word CONSTRUCTOR.
	(expand_expr, case CONSTRUCTOR): Fix errors in parms to assign_temp.

From-SVN: r47663
This commit is contained in:
Richard Kenner 2001-12-05 11:44:37 +00:00 committed by Richard Kenner
parent c56e3582c2
commit c24ae149dd
2 changed files with 30 additions and 34 deletions

View File

@ -1,5 +1,11 @@
Wed Dec 5 06:26:27 2001 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
* expr.c (store_expr): When copying string constant into array,
use functions that update memrefs instead of computations on
addresses to better track MEMs. Also properly handle 32/64 pointers.
(expand_expr): Use TARGET even if not reg for multi-word CONSTRUCTOR.
(expand_expr, case CONSTRUCTOR): Fix errors in parms to assign_temp.
* emit-rtl.c (component_ref_for_mem_expr): Try harder to find decl
underneath COMPONENT_REFs.
(set_mem_attributes): Also strip VIEW_CONVERT_EXPR.

View File

@ -4253,15 +4253,12 @@ store_expr (exp, target, want_value)
else if (GET_MODE (temp) == BLKmode && TREE_CODE (exp) == STRING_CST)
{
/* Handle copying a string constant into an array.
The string constant may be shorter than the array.
So copy just the string's actual length, and clear the rest. */
rtx size;
rtx addr;
/* Handle copying a string constant into an array. The string
constant may be shorter than the array. So copy just the string's
actual length, and clear the rest. First get the size of the data
type of the string, which is actually the size of the target. */
rtx size = expr_size (exp);
/* Get the size of the data type of the string,
which is actually the size of the target. */
size = expr_size (exp);
if (GET_CODE (size) == CONST_INT
&& INTVAL (size) < TREE_STRING_LENGTH (exp))
emit_block_move (target, temp, size);
@ -4277,30 +4274,31 @@ store_expr (exp, target, want_value)
rtx label = 0;
/* Copy that much. */
copy_size_rtx = convert_to_mode (ptr_mode, copy_size_rtx, 0);
emit_block_move (target, temp, copy_size_rtx);
/* Figure out how much is left in TARGET that we have to clear.
Do all calculations in ptr_mode. */
addr = XEXP (target, 0);
addr = convert_modes (ptr_mode, Pmode, addr, 1);
if (GET_CODE (copy_size_rtx) == CONST_INT)
{
addr = plus_constant (addr, TREE_STRING_LENGTH (exp));
size = plus_constant (size, -TREE_STRING_LENGTH (exp));
size = plus_constant (size, -INTVAL (copy_size_rtx));
target = adjust_address (target, BLKmode,
INTVAL (copy_size_rtx));
}
else
{
addr = force_reg (ptr_mode, addr);
addr = expand_binop (ptr_mode, add_optab, addr,
copy_size_rtx, NULL_RTX, 0,
OPTAB_LIB_WIDEN);
size = expand_binop (ptr_mode, sub_optab, size,
copy_size_rtx, NULL_RTX, 0,
OPTAB_LIB_WIDEN);
#ifdef POINTERS_EXTEND_UNSIGNED
if (GET_MODE (copy_size_rtx) != Pmode)
copy_size_rtx = convert_memory_address (Pmode,
copy_size_rtx);
#endif
target = offset_address (target, copy_size_rtx,
highest_pow2_factor (copy_size));
label = gen_label_rtx ();
emit_cmp_and_jump_insns (size, const0_rtx, LT, NULL_RTX,
GET_MODE (size), 0, label);
@ -4308,27 +4306,17 @@ store_expr (exp, target, want_value)
if (size != const0_rtx)
{
rtx dest = gen_rtx_MEM (BLKmode, addr);
MEM_COPY_ATTRIBUTES (dest, target);
/* The residual likely does not have the same alignment
as the original target. While we could compute the
alignment of the residual, it hardely seems worth
the effort. */
set_mem_align (dest, BITS_PER_UNIT);
/* Be sure we can write on ADDR. */
in_check_memory_usage = 1;
if (current_function_check_memory_usage)
emit_library_call (chkr_check_addr_libfunc,
LCT_CONST_MAKE_BLOCK, VOIDmode, 3,
addr, Pmode,
XEXP (target, 0), Pmode,
size, TYPE_MODE (sizetype),
GEN_INT (MEMORY_USE_WO),
TYPE_MODE (integer_type_node));
in_check_memory_usage = 0;
clear_storage (dest, size);
clear_storage (target, size);
}
if (label)
@ -6277,10 +6265,12 @@ expand_expr (exp, target, tmode, modifier)
/* If will do cse, generate all results into pseudo registers
since 1) that allows cse to find more things
and 2) otherwise cse could produce an insn the machine
cannot support. */
cannot support. And exception is a CONSTRUCTOR into a multi-word
MEM: that's much more likely to be most efficient into the MEM. */
if (! cse_not_expected && mode != BLKmode && target
&& (GET_CODE (target) != REG || REGNO (target) < FIRST_PSEUDO_REGISTER))
&& (GET_CODE (target) != REG || REGNO (target) < FIRST_PSEUDO_REGISTER)
&& ! (code == CONSTRUCTOR && GET_MODE_SIZE (mode) > UNITS_PER_WORD))
target = subtarget;
switch (code)
@ -6788,7 +6778,7 @@ expand_expr (exp, target, tmode, modifier)
(TYPE_QUALS (type)
| (TREE_READONLY (exp)
* TYPE_QUAL_CONST))),
TREE_ADDRESSABLE (exp), 1, 1);
0, TREE_ADDRESSABLE (exp), 1);
store_constructor (exp, target, 0,
int_size_in_bytes (TREE_TYPE (exp)));