On 07/28/11 06:40, Richard Guenther wrote:

Looking at the C++ memory model what you need is indeed simple enough
to recover here.  Still this loop does quadratic work for a struct with
N bitfield members and a function which stores into all of them.
And that with a big constant factor as you build a component-ref
and even unshare trees (which isn't necessary here anyway).  In fact
you could easily manually keep track of bitpos when walking adjacent
bitfield members.  An initial call to get_inner_reference on
TREE_OPERAND (exp, 0) would give you the starting position of the record.

That would still be quadratic of course.

Actually, we don't need to call get_inner_reference at all. It seems DECL_FIELD_BIT_OFFSET has all the information we need.

How about we simplify things further as in the attached patch?

Tested on x86-64 Linux.

OK for mainline?

        * expr.c (get_bit_range): Get field bit offset from
        DECL_FIELD_BIT_OFFSET.

Index: expr.c
===================================================================
--- expr.c      (revision 176891)
+++ expr.c      (working copy)
@@ -4179,18 +4179,10 @@ get_bit_range (unsigned HOST_WIDE_INT *b
   prev_field_is_bitfield = true;
   for (fld = TYPE_FIELDS (record_type); fld; fld = DECL_CHAIN (fld))
     {
-      tree t, offset;
-      enum machine_mode mode;
-      int unsignedp, volatilep;
-
       if (TREE_CODE (fld) != FIELD_DECL)
        continue;
 
-      t = build3 (COMPONENT_REF, TREE_TYPE (exp),
-                 unshare_expr (TREE_OPERAND (exp, 0)),
-                 fld, NULL_TREE);
-      get_inner_reference (t, &bitsize, &bitpos, &offset,
-                          &mode, &unsignedp, &volatilep, true);
+      bitpos = TREE_INT_CST_LOW (DECL_FIELD_BIT_OFFSET (fld));
 
       if (field == fld)
        found_field = true;

Reply via email to