Btw, *byte_offset is still not relative to the containing object as
documented, but relative to the base object of the exp reference
tree (thus, to a in a.i.j.k.l instead of to a.i.j.k).  If it were supposed
to be relative to a.i.j.k get_inner_reference would be not needed
either.  Can you clarify what "containing object" means in the
overall comment please?

I'm thoroughly confused here. Originally I had "inner decl", then we changed the nomenclature to "containing object", and now there's this "innermost reference".

What I mean to say is the "a" in a.i.j.k.l. How would you like me to call that? The innermost reference? The inner decl? Would this comment be acceptable:

   Given a COMPONENT_REF, this function calculates the byte offset
   from the innermost reference ("a" in a.i.j.k.l) to the start of the
   contiguous bit region containing the field in question.


If it is really relative to the innermost reference of exp you can
"CSE" the offset of TREE_OPERAND (exp, 0) and do relative
adjustments for all the other get_inner_reference calls.  For
example the

+  /* If we found the end of the bit field sequence, include the
+     padding up to the next field...  */
    if (fld)
      {
...
+      /* Calculate bitpos and offset of the next field.  */
+      get_inner_reference (build3 (COMPONENT_REF,
+                                  TREE_TYPE (exp),
+                                  TREE_OPERAND (exp, 0),
+                                  fld, NULL_TREE),
+                       &tbitsize,&end_bitpos,&end_offset,
+                       &tmode,&tunsignedp,&tvolatilep, true);

case is not correct anyway, fld may have variable position
(non-INTEGER_CST DECL_FIELD_OFFSET), you can't
assume

Innermost here means "a" in a.i.j.k.l? If so, this is what we're currently doing, *byte_offset is the start of the bit region, and *bit_offset is the offset from that.

First, I thought we couldn't get a variable position here because we are now handling that case at the beginning of the function with:

  /* Be as conservative as possible on variable offsets.  */
  if (TREE_OPERAND (exp, 2)
      && !host_integerp (TREE_OPERAND (exp, 2), 1))
    {
      *byte_offset = TREE_OPERAND (exp, 2);
      *maxbits = BITS_PER_UNIT;
      *bit_offset = 0;
      return;
    }

And even if we do get a variable position, I have so far being able to get away with this...


+      *maxbits = TREE_INT_CST_LOW (maxbits_tree);

this thus.

...because the call to fold_build2 immediately preceding this will fold away the variable offset.

Is what you want, that we call get_inner_reference once, and then use DECL_FIELD_OFFSET+DECL_FIELD_BIT_OFFSET to calculate any subsequent bit offset? I found this to be quite tricky with padding, and such, but am willing to give it a whirl again.

However, could I beg you to reconsider this, and get something working first, only later concentrating on removing the get_inner_reference() calls, and performing any other tweaks/optimizations?

Aldy

Reply via email to