summaryrefslogtreecommitdiff
path: root/gcc/expr.c
diff options
context:
space:
mode:
authorebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4>2012-09-14 13:28:44 +0000
committerebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4>2012-09-14 13:28:44 +0000
commit2d0fd66d982886cf217f7127f2d906fed5df9374 (patch)
tree5c32661073d991fc5ce315762062115ab0af337c /gcc/expr.c
parent9579a4b96330010a9a9b327eec8dfd4be1d3524d (diff)
downloadgcc-2d0fd66d982886cf217f7127f2d906fed5df9374.tar.gz
PR rtl-optimization/44194
* calls.c (expand_call): In the PARALLEL case, copy the return value into pseudos instead of spilling it onto the stack. * emit-rtl.c (adjust_address_1): Rename ADJUST into ADJUST_ADDRESS and add new ADJUST_OBJECT parameter. If ADJUST_OBJECT is set, drop the underlying object if it cannot be proved that the adjusted memory access is still within its bounds. (adjust_automodify_address_1): Adjust call to adjust_address_1. (widen_memory_access): Likewise. * expmed.c (store_bit_field_1): Call adjust_bitfield_address instead of adjust_address. Do not drop the underlying object of a MEM. (store_fixed_bit_field): Likewise. (extract_bit_field_1): Likewise. Fix oversight in recursion. (extract_fixed_bit_field): Likewise. * expr.h (adjust_address_1): Adjust prototype. (adjust_address): Adjust call to adjust_address_1. (adjust_address_nv): Likewise. (adjust_bitfield_address): New macro. (adjust_bitfield_address_nv): Likewise. * expr.c (expand_assignment): Handle a PARALLEL in more cases. (store_expr): Likewise. (store_field): Likewise. * dse.c: Fix typos in the head comment. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@191302 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/expr.c')
-rw-r--r--gcc/expr.c57
1 files changed, 43 insertions, 14 deletions
diff --git a/gcc/expr.c b/gcc/expr.c
index 2ed2f960aa6..c53f1a8dc9b 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -4870,8 +4870,16 @@ expand_assignment (tree to, tree from, bool nontemporal)
/* Handle calls that return values in multiple non-contiguous locations.
The Irix 6 ABI has examples of this. */
if (GET_CODE (to_rtx) == PARALLEL)
- emit_group_load (to_rtx, value, TREE_TYPE (from),
- int_size_in_bytes (TREE_TYPE (from)));
+ {
+ if (GET_CODE (value) == PARALLEL)
+ emit_group_move (to_rtx, value);
+ else
+ emit_group_load (to_rtx, value, TREE_TYPE (from),
+ int_size_in_bytes (TREE_TYPE (from)));
+ }
+ else if (GET_CODE (value) == PARALLEL)
+ emit_group_store (to_rtx, value, TREE_TYPE (from),
+ int_size_in_bytes (TREE_TYPE (from)));
else if (GET_MODE (to_rtx) == BLKmode)
emit_block_move (to_rtx, value, expr_size (from), BLOCK_OP_NORMAL);
else
@@ -4903,9 +4911,16 @@ expand_assignment (tree to, tree from, bool nontemporal)
else
temp = expand_expr (from, NULL_RTX, GET_MODE (to_rtx), EXPAND_NORMAL);
+ /* Handle calls that return values in multiple non-contiguous locations.
+ The Irix 6 ABI has examples of this. */
if (GET_CODE (to_rtx) == PARALLEL)
- emit_group_load (to_rtx, temp, TREE_TYPE (from),
- int_size_in_bytes (TREE_TYPE (from)));
+ {
+ if (GET_CODE (temp) == PARALLEL)
+ emit_group_move (to_rtx, temp);
+ else
+ emit_group_load (to_rtx, temp, TREE_TYPE (from),
+ int_size_in_bytes (TREE_TYPE (from)));
+ }
else if (temp)
emit_move_insn (to_rtx, temp);
@@ -5299,16 +5314,22 @@ store_expr (tree exp, rtx target, int call_param_p, bool nontemporal)
/* Handle calls that return values in multiple non-contiguous locations.
The Irix 6 ABI has examples of this. */
else if (GET_CODE (target) == PARALLEL)
- emit_group_load (target, temp, TREE_TYPE (exp),
- int_size_in_bytes (TREE_TYPE (exp)));
+ {
+ if (GET_CODE (temp) == PARALLEL)
+ emit_group_move (target, temp);
+ else
+ emit_group_load (target, temp, TREE_TYPE (exp),
+ int_size_in_bytes (TREE_TYPE (exp)));
+ }
+ else if (GET_CODE (temp) == PARALLEL)
+ emit_group_store (target, temp, TREE_TYPE (exp),
+ int_size_in_bytes (TREE_TYPE (exp)));
else if (GET_MODE (temp) == BLKmode)
emit_block_move (target, temp, expr_size (exp),
(call_param_p
? BLOCK_OP_CALL_PARM : BLOCK_OP_NORMAL));
- else if (nontemporal
- && emit_storent_insn (target, temp))
- /* If we managed to emit a nontemporal store, there is nothing else to
- do. */
+ /* If we emit a nontemporal store, there is nothing else to do. */
+ else if (nontemporal && emit_storent_insn (target, temp))
;
else
{
@@ -6429,10 +6450,18 @@ store_field (rtx target, HOST_WIDE_INT bitsize, HOST_WIDE_INT bitpos,
return const0_rtx;
}
- /* Store the value in the bitfield. */
- store_bit_field (target, bitsize, bitpos,
- bitregion_start, bitregion_end,
- mode, temp);
+ /* Handle calls that return values in multiple non-contiguous locations.
+ The Irix 6 ABI has examples of this. */
+ if (bitpos == 0
+ && bitsize == GET_MODE_BITSIZE (mode)
+ && GET_CODE (temp) == PARALLEL)
+ emit_group_store (target, temp, TREE_TYPE (exp),
+ int_size_in_bytes (TREE_TYPE (exp)));
+ else
+ /* Store the value in the bitfield. */
+ store_bit_field (target, bitsize, bitpos,
+ bitregion_start, bitregion_end,
+ mode, temp);
return const0_rtx;
}