From 7fbf8a3ede761711ffed9a8658746db31bfbd0e1 Mon Sep 17 00:00:00 2001 From: Bernd Edlinger <bernd.edlinger@hotmail.de> Date: Wed, 28 May 2014 13:37:02 +0000 Subject: [PATCH] expr.c (expand_assignment): Fold the bitpos in the to_rtx if sufficiently aligned and an offset is used at... 2014-05-28 Bernd Edlinger <bernd.edlinger@hotmail.de> * expr.c (expand_assignment): Fold the bitpos in the to_rtx if sufficiently aligned and an offset is used at the same time. (expand_expr_real_1): Likewise. From-SVN: r211020 --- gcc/ChangeLog | 6 ++++++ gcc/expr.c | 37 +++++++++++++++++++++++++------------ 2 files changed, 31 insertions(+), 12 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 76d4a66f3226..7d888f8863ac 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2014-05-28 Bernd Edlinger <bernd.edlinger@hotmail.de> + + * expr.c (expand_assignment): Fold the bitpos in the to_rtx if + sufficiently aligned and an offset is used at the same time. + (expand_expr_real_1): Likewise. + 2014-05-28 Richard Biener <rguenther@suse.de> PR middle-end/61045 diff --git a/gcc/expr.c b/gcc/expr.c index 2868d9d3443e..d99bc1ef9fba 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -4838,15 +4838,29 @@ expand_assignment (tree to, tree from, bool nontemporal) if (GET_MODE (offset_rtx) != address_mode) offset_rtx = convert_to_mode (address_mode, offset_rtx, 0); - /* The check for a constant address in TO_RTX not having VOIDmode - is probably no longer necessary. */ - if (MEM_P (to_rtx) - && GET_MODE (to_rtx) == BLKmode - && GET_MODE (XEXP (to_rtx, 0)) != VOIDmode + /* If we have an expression in OFFSET_RTX and a non-zero + byte offset in BITPOS, adding the byte offset before the + OFFSET_RTX results in better intermediate code, which makes + later rtl optimization passes perform better. + + We prefer intermediate code like this: + + r124:DI=r123:DI+0x18 + [r124:DI]=r121:DI + + ... instead of ... + + r124:DI=r123:DI+0x10 + [r124:DI+0x8]=r121:DI + + This is only done for aligned data values, as these can + be expected to result in single move instructions. */ + if (mode1 != VOIDmode + && bitpos != 0 && bitsize > 0 && (bitpos % bitsize) == 0 && (bitsize % GET_MODE_ALIGNMENT (mode1)) == 0 - && MEM_ALIGN (to_rtx) == GET_MODE_ALIGNMENT (mode1)) + && MEM_ALIGN (to_rtx) >= GET_MODE_ALIGNMENT (mode1)) { to_rtx = adjust_address (to_rtx, mode1, bitpos / BITS_PER_UNIT); bitregion_start = 0; @@ -10090,14 +10104,13 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode, if (GET_MODE (offset_rtx) != address_mode) offset_rtx = convert_to_mode (address_mode, offset_rtx, 0); - if (GET_MODE (op0) == BLKmode - /* The check for a constant address in OP0 not having VOIDmode - is probably no longer necessary. */ - && GET_MODE (XEXP (op0, 0)) != VOIDmode - && bitsize != 0 + /* See the comment in expand_assignment for the rationale. */ + if (mode1 != VOIDmode + && bitpos != 0 + && bitsize > 0 && (bitpos % bitsize) == 0 && (bitsize % GET_MODE_ALIGNMENT (mode1)) == 0 - && MEM_ALIGN (op0) == GET_MODE_ALIGNMENT (mode1)) + && MEM_ALIGN (op0) >= GET_MODE_ALIGNMENT (mode1)) { op0 = adjust_address (op0, mode1, bitpos / BITS_PER_UNIT); bitpos = 0;