diff options
author | Richard Kenner <kenner@vlsi1.ultra.nyu.edu> | 2001-12-05 11:44:37 +0000 |
---|---|---|
committer | Richard Kenner <kenner@gcc.gnu.org> | 2001-12-05 06:44:37 -0500 |
commit | c24ae149dd6cec1b08f21d99c8db45fe9ba3f442 (patch) | |
tree | 4802ce8c96eb6abfe2ed68fb1dabe77ef37593b1 | |
parent | c56e3582c20263c442e00da7ea484edf9c912165 (diff) | |
download | gcc-c24ae149dd6cec1b08f21d99c8db45fe9ba3f442.zip gcc-c24ae149dd6cec1b08f21d99c8db45fe9ba3f442.tar.gz gcc-c24ae149dd6cec1b08f21d99c8db45fe9ba3f442.tar.bz2 |
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
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/expr.c | 58 |
2 files changed, 30 insertions, 34 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index dad21bf..2476e32 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -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. @@ -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))); |