Patchwork [C++0x] contiguous bitfields race implementation

login
register
mail settings
Submitter Aldy Hernandez
Date July 29, 2011, 2:12 a.m.
Message ID <4E3216F7.10504@redhat.com>
Download mbox | patch
Permalink /patch/107372/
State New
Headers show

Comments

Aldy Hernandez - July 29, 2011, 2:12 a.m.
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.

Patch

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;