]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
2012-05-09 Richard Guenther <rguenther@suse.de>
authorrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 9 May 2012 08:56:25 +0000 (08:56 +0000)
committerrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 9 May 2012 08:56:25 +0000 (08:56 +0000)
* stor-layout.c (bit_from_pos): Document.
(byte_from_pos): Likewise.  Optimize.
(pos_from_bit): Likewise.
(normalize_offset): Use pos_from_bit instead of replicating it.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@187317 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/stor-layout.c

index 3894d41deaf0490e28412a4e22b2b6b68e5799f7..86a59eff84678742e8718180f3d0c0d05705306f 100644 (file)
@@ -1,3 +1,10 @@
+2012-05-09  Richard Guenther  <rguenther@suse.de>
+
+       * stor-layout.c (bit_from_pos): Document.
+       (byte_from_pos): Likewise.  Optimize.
+       (pos_from_bit): Likewise.
+       (normalize_offset): Use pos_from_bit instead of replicating it.
+
 2012-05-09  Alan Modra  <amodra@gmail.com>
 
        PR target/53271
index 12a6c13a6b8d1bf71a57145e71c7beff0ec10b79..fb00b5f4bb22b5825c10846a51119f18e03af790 100644 (file)
@@ -785,8 +785,8 @@ start_record_layout (tree t)
   return rli;
 }
 
-/* These four routines perform computations that convert between
-   the offset/bitpos forms and byte and bit offsets.  */
+/* Return the combined bit position for the byte offset OFFSET and the
+   bit position BITPOS.  */
 
 tree
 bit_from_pos (tree offset, tree bitpos)
@@ -797,25 +797,46 @@ bit_from_pos (tree offset, tree bitpos)
                                 bitsize_unit_node));
 }
 
+/* Return the combined truncated byte position for the byte offset OFFSET and
+   the bit position BITPOS.  */
+
 tree
 byte_from_pos (tree offset, tree bitpos)
 {
-  return size_binop (PLUS_EXPR, offset,
-                    fold_convert (sizetype,
-                                  size_binop (TRUNC_DIV_EXPR, bitpos,
-                                              bitsize_unit_node)));
+  tree bytepos;
+  if (TREE_CODE (bitpos) == MULT_EXPR
+      && tree_int_cst_equal (TREE_OPERAND (bitpos, 1), bitsize_unit_node))
+    bytepos = TREE_OPERAND (bitpos, 0);
+  else
+    bytepos = size_binop (TRUNC_DIV_EXPR, bitpos, bitsize_unit_node);
+  return size_binop (PLUS_EXPR, offset, fold_convert (sizetype, bytepos));
 }
 
+/* Split the bit position POS into a byte offset *POFFSET and a bit
+   position *PBITPOS with the byte offset aligned to OFF_ALIGN bits.  */
+
 void
 pos_from_bit (tree *poffset, tree *pbitpos, unsigned int off_align,
              tree pos)
 {
-  *poffset = size_binop (MULT_EXPR,
-                        fold_convert (sizetype,
-                                      size_binop (FLOOR_DIV_EXPR, pos,
-                                                  bitsize_int (off_align))),
-                        size_int (off_align / BITS_PER_UNIT));
-  *pbitpos = size_binop (FLOOR_MOD_EXPR, pos, bitsize_int (off_align));
+  tree toff_align = bitsize_int (off_align);
+  if (TREE_CODE (pos) == MULT_EXPR
+      && tree_int_cst_equal (TREE_OPERAND (pos, 1), toff_align))
+    {
+      *poffset = size_binop (MULT_EXPR,
+                            fold_convert (sizetype, TREE_OPERAND (pos, 0)),
+                            size_int (off_align / BITS_PER_UNIT));
+      *pbitpos = bitsize_zero_node;
+    }
+  else
+    {
+      *poffset = size_binop (MULT_EXPR,
+                            fold_convert (sizetype,
+                                          size_binop (FLOOR_DIV_EXPR, pos,
+                                                      toff_align)),
+                            size_int (off_align / BITS_PER_UNIT));
+      *pbitpos = size_binop (FLOOR_MOD_EXPR, pos, toff_align);
+    }
 }
 
 /* Given a pointer to bit and byte offsets and an offset alignment,
@@ -828,17 +849,10 @@ normalize_offset (tree *poffset, tree *pbitpos, unsigned int off_align)
      downwards.  */
   if (compare_tree_int (*pbitpos, off_align) >= 0)
     {
-      tree extra_aligns = size_binop (FLOOR_DIV_EXPR, *pbitpos,
-                                     bitsize_int (off_align));
-
-      *poffset
-       = size_binop (PLUS_EXPR, *poffset,
-                     size_binop (MULT_EXPR,
-                                 fold_convert (sizetype, extra_aligns),
-                                 size_int (off_align / BITS_PER_UNIT)));
-
-      *pbitpos
-       = size_binop (FLOOR_MOD_EXPR, *pbitpos, bitsize_int (off_align));
+      tree offset, bitpos;
+      pos_from_bit (&offset, &bitpos, off_align, *pbitpos);
+      *poffset = size_binop (PLUS_EXPR, *poffset, offset);
+      *pbitpos = bitpos;
     }
 }