This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
fix 23630
- From: Richard Henderson <rth at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Tue, 30 Aug 2005 21:59:58 -0700
- Subject: fix 23630
This performance regression is fallout due to the fix for pr23517.
Fixed by not being so pessimistic about dumping data to memory.
The semantics of gen_lowpart exactly match V_C_E when the mode
sizes match. They probably match up even more often, such as
integer low parts of double values. But that's not really
relevant to the PR, so I've ignored it.
r~
* expr.c (expand_expr_real_1) <VIEW_CONVERT_EXPR>: Use gen_lowpart
whenever the mode sizes match.
Index: expr.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/expr.c,v
retrieving revision 1.778.6.2
diff -u -p -d -r1.778.6.2 expr.c
--- expr.c 4 May 2005 07:35:17 -0000 1.778.6.2
+++ expr.c 31 Aug 2005 04:50:56 -0000
@@ -7392,18 +7392,23 @@ expand_expr_real_1 (tree exp, rtx target
case VIEW_CONVERT_EXPR:
op0 = expand_expr (TREE_OPERAND (exp, 0), NULL_RTX, mode, modifier);
- /* If the input and output modes are both the same, we are done.
- Otherwise, if neither mode is BLKmode and both are integral and within
- a word, we can use gen_lowpart. If neither is true, make sure the
- operand is in memory and convert the MEM to the new mode. */
+ /* If the input and output modes are both the same, we are done. */
if (TYPE_MODE (type) == GET_MODE (op0))
;
+ /* If neither mode is BLKmode, and both modes are the same size
+ then we can use gen_lowpart. */
else if (TYPE_MODE (type) != BLKmode && GET_MODE (op0) != BLKmode
- && GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT
- && GET_MODE_CLASS (TYPE_MODE (type)) == MODE_INT
- && GET_MODE_SIZE (TYPE_MODE (type)) <= UNITS_PER_WORD
- && GET_MODE_SIZE (GET_MODE (op0)) <= UNITS_PER_WORD)
+ && GET_MODE_SIZE (TYPE_MODE (type))
+ == GET_MODE_SIZE (GET_MODE (op0)))
op0 = gen_lowpart (TYPE_MODE (type), op0);
+ /* If both modes are integral, then we can convert from one to the
+ other. */
+ else if (SCALAR_INT_MODE_P (GET_MODE (op0))
+ && SCALAR_INT_MODE_P (TYPE_MODE (type)))
+ op0 = convert_modes (TYPE_MODE (type), GET_MODE (op0), op0,
+ TYPE_UNSIGNED (TREE_TYPE (TREE_OPERAND (exp, 0))));
+ /* As a last resort, spill op0 to memory, and reload it in a
+ different mode. */
else if (!MEM_P (op0))
{
/* If the operand is not a MEM, force it into memory. Since we