]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
expr.c (expand_assignment): Fold the bitpos in the to_rtx if sufficiently aligned...
authorBernd Edlinger <bernd.edlinger@hotmail.de>
Wed, 28 May 2014 13:37:02 +0000 (13:37 +0000)
committerBernd Edlinger <edlinger@gcc.gnu.org>
Wed, 28 May 2014 13:37:02 +0000 (13:37 +0000)
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
gcc/expr.c

index 76d4a66f3226a70851371f00f1439e5252435e72..7d888f8863acc823ddd9ba2c99b84b84524761ac 100644 (file)
@@ -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
index 2868d9d3443e7ce568793d9bff453038e62f7a83..d99bc1ef9fba674a18538817457675b6813d005a 100644 (file)
@@ -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;