diff options
author | ebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-09-14 13:28:44 +0000 |
---|---|---|
committer | ebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-09-14 13:28:44 +0000 |
commit | 2d0fd66d982886cf217f7127f2d906fed5df9374 (patch) | |
tree | 5c32661073d991fc5ce315762062115ab0af337c /gcc/expr.c | |
parent | 9579a4b96330010a9a9b327eec8dfd4be1d3524d (diff) | |
download | gcc-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.c | 57 |
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; } |