This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Constrain valid arguments to BIT_FIELD_REF


On Mar  4, 2008, Richard Guenther <rguenther@suse.de> wrote:

> the type of the result is unspecified.

???  You mean, other than by TREE_TYPE of the BIT_FIELD_REF?  I'm
pretty sure that's what specifies the type of the result.

> I suggest to make sure that bit position and size are constants,

+1

> the object referenced is of integral type

This would break the use of SRA to extract sub-objects of non-integral
type.  IIRC Ada does such things.

> the result type is of the same type as the operand zero type

Err, this doesn't make much sense to me.  Consider:

struct {
  int i:3;
  unsigned j:5;
} k;

int foo(int x, unsigned y)
  k.i = x;
  k.j = y;

  bar ();

  return k.i + k.j;
}


Now, I want to extract i or j from k.  For starters, k's type is
not an integral type.  i and j are components in the same word, but
with different types themselves.

It seems like what you're proposing would require explicit
VIEW_CONVERT_EXPRs from k to some integral type, then a BIT_FIELD_REF
that extracts bits into the same type, and then some other conversion
to the type with the width and precision of the field type.

This is not just a lot of explicit conversion that might very well be
encoded in BIT_FIELD_REF by avoiding its now-redundant TREE_TYPE (not
necessarily a bad thing), but also a requirement for significantly
different code paths to handle the two cases, which AFAICT will both
lead to poorer optimization.

E.g., how do you envision generating code for foo() above?  (The call
to bar() is there just to prevent the accesses to k from being
short-circuited, such that reads and writes are both clearly spelled
out).

FWIW, what we (could) do now is something along the lines of:

  BIT_FIELD_REF(int)<k, 3, 0> = x;
  BIT_FIELD_REF(unsigned)<k, 5, 3> = y;
  bar();
  T.1 = BIT_FIELD_REF(int)<k, 3, 0>;
  T.2 = BIT_FIELD_REF(unsigned)<k, 5, 3>;
  T.3 = (int)T.2;
  T.4 = T.1 + T.3;
  return T.4;

> (and not a bitfield type of the referenced size -- in which case the
> BIT_FIELD_REF_UNSIGNED would be useless)

There's no such thing as a language-independent bitfield type of the
referenced size.  When you ask for an integral type with a certain bit
width, you may get a wider type, even with a wider precision.  And
that's where BIT_FIELD_REF_UNSIGNED should come into play, although I
remember I had to deal with some inconsistencies in the handling of
this stuff while working on SRA.

> fold currently optimizes a.b.c == 0 to BIT_FIELD_REF <a, 8, big-num> & 1
> for bit field field-decls c.  IMHO this is bad because it pessimizes
> TBAA (needs to use a's alias set, not the underlying integral type
> alias set) and it "breaks" type correctness as arbitrary structure
> types appear as operand zero.

I don't quite see how this breaks type correctness, can you elaborate?

I understand the problem about alias sets.  Ideally, if we're
accessing part of an object with BIT_FIELD_REF, it would be useful to
narrow the alias set such that only the alias sets of the fields
present in words related with that region get a say in the aliasing
properties of this statement.  For BIT_FIELD_REFs used only as inputs,
we could even do with the alias sets of fields that are within the
range [big-num,big-num + 8), but for those used as outputs, it seems
to me that we may need to bring in adjacent fields within the same
words to ensure correctness for MEM accesses after the BIT_FIELD_REF
write is broken down into read and write operations which may be
intermixed by schedule with other operations on the same words.

Makes sense?

-- 
Alexandre Oliva         http://www.lsd.ic.unicamp.br/~oliva/
FSF Latin America Board Member         http://www.fsfla.org/
Red Hat Compiler Engineer   aoliva@{redhat.com, gcc.gnu.org}
Free Software Evangelist  oliva@{lsd.ic.unicamp.br, gnu.org}


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]