summaryrefslogtreecommitdiff
path: root/gcc/stor-layout.c
diff options
context:
space:
mode:
authorrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>2012-05-09 08:56:25 +0000
committerrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>2012-05-09 08:56:25 +0000
commit2765f7eb0342e6709a7d4674d5b2196fe14b0ebd (patch)
tree995b14c92a109cf36a66ce3adab16fa988b2958d /gcc/stor-layout.c
parent11dd6494939dd5a8fa7b62ff21164926f55aeab3 (diff)
downloadgcc-2765f7eb0342e6709a7d4674d5b2196fe14b0ebd.tar.gz
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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@187317 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/stor-layout.c')
-rw-r--r--gcc/stor-layout.c60
1 files changed, 37 insertions, 23 deletions
diff --git a/gcc/stor-layout.c b/gcc/stor-layout.c
index 12a6c13a6b8..fb00b5f4bb2 100644
--- a/gcc/stor-layout.c
+++ b/gcc/stor-layout.c
@@ -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;
}
}