public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* Re: Patch to allow Ada to work with tree-ssa
@ 2004-06-22 20:22 Richard Kenner
  2004-06-22 20:30 ` Mark Mitchell
  0 siblings, 1 reply; 77+ messages in thread
From: Richard Kenner @ 2004-06-22 20:22 UTC (permalink / raw)
  To: mark; +Cc: gcc-patches

    I'm not disputing that you fixed a bug with these patches; what I'm 
    saying is that there must be a better way to fix it.

I'm open to the possibility of there being a better way to fix it, but
nobody's come up with one yet.  This was not my first choice.  As I said, my
first proposal was indeed to do this without increasing the size of the nodes
(which I didn't care for either), but that was strongly opposed by many people.

    Many of us cannot read GCC mail on a continuous basis.  

Yeah, but I'd say it's rare to read gcc-patches on a more continuous basis
than the GCC list!

    It's was originally a C and C++-specific file; now, it's the closest 
    thing we have to tree documentation.  It certainly documents ARRAY_REF 
    and COMPONENT_REF.

OK, I can add it to that, but I suggest that somebody with access to the
repository rename the file to a more lanuage-independent name.

    In their plain English meaning, the words you wrote in tree.def make
    these fields redundant; you have defined the values of these fields in
    terms of information already available in the tree.  You've suggested
    that this is not actually true; that they are conveying some
    information not already present -- but the words you've written do not
    make clear what that is.  For example, "Operand 2 is a copy of
    TYPE_MIN_VALUE of the index."  OK, then, why don't we just do
    TYPE_MIN_VALUE (TREE_TYE (TREE_OEPRAND (x, 1)))?  Why store this in
    the node?  That is not explained in your documentation.

OK.  Will fix.

    I am very much against increasing the size of COMPONENT_REF and
    ARRAY_REF for C++.  I've suggested a technical solution: add a flag to
    the nodes that says whether they have all the fields, or just the old
    ones.  Presumably, it will be very rare in C/C++ to have all the
    fields.  True, we don't have that yet -- but, I'm confident you can
    find a way.

Sure, I can "find a way" to have such a flag, but doing it in general is
going to have a cost penalty because TREE_OPERAND would have to become a
call.  We'd be trading a very small size cost for a large compute cost.
Better would be to have two node types, but that would complicate GIMPLE,
which also has its downside.

    I recognize that you estimated conservatively, 

*very* conservatively!

Nathan and Zack, what are the actual percentage of ARRAY_REF and
COMPONENT_REF?  I used 12.5% and 25%, but it wouldn't surprise me if that was
high by a factor of at least four.

    but we should not be making changes that increase memory usage,

As they say, "you can't make an omelet without breakings eggs". Although
keeping memory usage down is a worthwhile goal, it's not an absolute.  After
all, the concept of gimplifying creates extra nodes, as does tree-ssa.  One
of the major things discussed at the GCC summit was to add more annotations
to names and that takes memory.  A discussion that I started last week led to
a belief that an UID concept for statements is important for debugging the
compiler and that will take space too.

    That's fine with me if you will agree to implement the optimization
    where these nodes are smaller when the extra fields are not needed, or
    implement new tree nodes for VARIABLE_ARRAY_REF or
    VARIABLE_COMPONENT_REF.  An even easier change would be to embed the
    additional fields in one of the existing operands; have the second
    operand be a TREE_LIST, or some such, in the case where there is a
    need for this additional information.  Ugly, but effective.

Certainly, I'll be glad to make a pass over this change and implement
something else, but both of the above have the attribues that they are in
GIMPLE and hence need to be known about by all the tree optimizers.

Another approach that would address your concerns about permanent memory,
would be to go the other way and have the nodes used by the front end for
ARRAY_REF and COMPONENT_REF be different from those used by the tree
optimizers (the latter will always have four fields) and have the gimplifier
convert.

But I'd also like to see Nathan and Zack weigh in here because their work
may become relevant too and they'll have the accurate statistics.

^ permalink raw reply	[flat|nested] 77+ messages in thread
* Re: Patch to allow Ada to work with tree-ssa
@ 2004-07-29 19:02 Richard Kenner
  0 siblings, 0 replies; 77+ messages in thread
From: Richard Kenner @ 2004-07-29 19:02 UTC (permalink / raw)
  To: rth; +Cc: gcc-patches

    >     Given a volatile variable 'x', '&x' is not marked TREE_CONSTANT,
    > 
    > Why?  That seems wrong.  The address of a volatile variable is still
    > constant.

    TREE_CONSTANT != TREE_INVARIANT.

    Addresses of global variables fall into the former category,
    addresses of stack variables fall into the later category.

Yes, I most certainly understand that.  But what does that have to do with
the issue of volatility?

    > I think the bug is that &x should be constant irrespective of the
    > volatility of X.

    We did.  You screwed up the test.

Who is "you" and which test do you mean?  And what do you mean by "we did"?

It looks like everybody calls recompute_tree_invarant_for_addr_expr (I just
noticed that name's had a typo in it) and that seems to do the right thing.
I modified that function, but I think it got the volatile case right even
before that.  So I'm quite confused.

^ permalink raw reply	[flat|nested] 77+ messages in thread
* Re: Patch to allow Ada to work with tree-ssa
@ 2004-07-29 18:43 Richard Kenner
  0 siblings, 0 replies; 77+ messages in thread
From: Richard Kenner @ 2004-07-29 18:43 UTC (permalink / raw)
  To: dnovillo; +Cc: gcc-patches

    The FE ought to set TREE_INVARIANT on ADDR_EXPRs, when appropriate.

I don't see that as the responsibility of a front end, but of build1 in tree.c.
We want all front ends to do exactly the same thing here.

^ permalink raw reply	[flat|nested] 77+ messages in thread
* Re: Patch to allow Ada to work with tree-ssa
@ 2004-07-29 17:12 Richard Kenner
  2004-07-29 17:13 ` Diego Novillo
  2004-07-29 17:57 ` Richard Henderson
  0 siblings, 2 replies; 77+ messages in thread
From: Richard Kenner @ 2004-07-29 17:12 UTC (permalink / raw)
  To: dnovillo; +Cc: gcc-patches

    Given a volatile variable 'x', '&x' is not marked TREE_CONSTANT,

Why?  That seems wrong.  The address of a volatile variable is still
constant.  recompute_tree_invarant_for_addr_expr correctly knows that
the address of a volatile decl is constant and invariant.

    Could you elaborate why exactly is_gimple_invariant is not sufficient
    here?  I am about to revert this patch, unless you can give me a test
    case.

Judging from the timing of the patch, the test case was the compiler itself
since I hadn't started working on the ACATS yet.  I'm not sure, but I believe
the issue had to do with the fact that the stack isn't constant, only
invariant, but I don't remember exactly what trouble that caused and where.

    We do need to get the case 'p = &x', so something will need to change here.

I think the bug is that &x should be constant irrespective of the volatility
of X.

^ permalink raw reply	[flat|nested] 77+ messages in thread
* Re: Patch to allow Ada to work with tree-ssa
@ 2004-06-25 15:28 Richard Kenner
  2004-06-28 15:09 ` Paolo Bonzini
  0 siblings, 1 reply; 77+ messages in thread
From: Richard Kenner @ 2004-06-25 15:28 UTC (permalink / raw)
  To: jsm; +Cc: gcc-patches

    That is only the case over a sufficiently long period of time that
    developers can reasonably be supposed generally to have upgraded their
    hardware.  I don't find three years such a period of time.

I do.  I think most people upgrade at about that interval: 2-3 years.
One other thing that's happening is that the cost of a new machines,
measured in hours of a person's time, is going *way* down.

When I first started working with computers, a high-end machine cost 52
*years* of typical salaries.  Now we're talking about well under a week's
salary to buy the fastest possible machine (perhaps as little as a day).

    > From my perspective, bootstrap times have gone from nearly 24 hours
    > when I first started working on GCC to 25 minutes recently and the
    > latter includes Ada and Java, which were not in the 24 hour figure.

    Is that 25 minutes a full toplevel "configure && make bootstrap"
    (including all runtime libraries)?  Does it include toplevel "make check"?

No.  I meant literally the bootstrap: the time to do three sets of builds of
the compiler.  Adding in the library and testsuite costs is a factor of
around 5 to that, but there's no similar comparison point "back in the days".

    I don't recall specific figures for bootstrap times when I first built
    2.7.x around 1996/7 on eight-times-slower hardware, but I think it was
    much quicker than now

I'm talking about ten years before that and on hardware that's probably
nearly 1,000 times slower (a Sun 3).

^ permalink raw reply	[flat|nested] 77+ messages in thread
* Re: Patch to allow Ada to work with tree-ssa
@ 2004-06-24 15:58 Richard Kenner
  2004-06-24 16:04 ` Nathan Sidwell
  2004-06-25 14:43 ` Joseph S. Myers
  0 siblings, 2 replies; 77+ messages in thread
From: Richard Kenner @ 2004-06-24 15:58 UTC (permalink / raw)
  To: jsm; +Cc: gcc-patches

    As illustrated by the growth of GCC itself.  My bootstrap plus testsuite
    run times on constant hardware have gone from under one hour a bit over
    three years ago to over three hours now (and this is artificially low
    because of the temporary disabling of Ada).  Much of this is the growth in
    GCC itself, but a significant part must be GCC slowing down.

Well, sure, but constant hardware isn't a good model of what's out there.
From my perspective, bootstrap times have gone from nearly 24 hours
when I first started working on GCC to 25 minutes recently and the
latter includes Ada and Java, which were not in the 24 hour figure.

^ permalink raw reply	[flat|nested] 77+ messages in thread
* Re: Patch to allow Ada to work with tree-ssa
@ 2004-06-23  5:54 Richard Kenner
  0 siblings, 0 replies; 77+ messages in thread
From: Richard Kenner @ 2004-06-23  5:54 UTC (permalink / raw)
  To: mckinlay; +Cc: aph, gcc-patches, java

    Yeah, gcj won't work without extra arguments if libgcj isn't installed. 
    Instead you can do this, from the libjava build directory:

    make check RUNTESTFLAGS="lang.exp=err6"

That worked.

And more importantly, the fix I mentioned did deal with this test case.

^ permalink raw reply	[flat|nested] 77+ messages in thread
* Re: Patch to allow Ada to work with tree-ssa
@ 2004-06-23  2:32 Richard Kenner
  2004-06-23  4:54 ` Bryce McKinlay
  0 siblings, 1 reply; 77+ messages in thread
From: Richard Kenner @ 2004-06-23  2:32 UTC (permalink / raw)
  To: mckinlay; +Cc: aph, gcc-patches, java

    >I don't know how to run Java code, though.  Can you tell me the
    >command-line options I need with the file you provided to see the problem?

    gcj err6.java --main=err6

I tried what I thought was the version of that which I was supposed to 
use while in the directoryof err6.java and got:

don% /gcc/gcc/i386-64-h/gcc/gcj -v -B/gcc/gcc/i386-64-h/gcc/ err6.java --main=err6
Reading specs from /gcc/gcc/i386-64-h/gcc/specs
Reading specs from libgcj.spec
gcj: libgcj.spec: No such file or directory

If I do the exact above command in the build directory but substitute
err6.java with the directory it's in, it uses the install gcj, not the
one in the build directory.  

If I do ./gcj ... I get:

don% ./gcj /gcc/gcc/test/err6.java --main=err6 -v
Using built-in specs.
Reading specs from libgcj.spec
gcj: libgcj.spec: No such file or directory

^ permalink raw reply	[flat|nested] 77+ messages in thread
* Re: Patch to allow Ada to work with tree-ssa
@ 2004-06-23  0:16 Richard Kenner
  0 siblings, 0 replies; 77+ messages in thread
From: Richard Kenner @ 2004-06-23  0:16 UTC (permalink / raw)
  To: paul; +Cc: gcc-patches

    It's a variable. Indeed it can change between uses within the same
    function, as I said last time this was discussed.

That wasn't clear.

    The gimplifier has the option of getting it from the type node.

Sure.  That's indeed what it does now.  But remember that we're talking
about both the node formats for GIMPLE and GENERIC.

^ permalink raw reply	[flat|nested] 77+ messages in thread
* Re: Patch to allow Ada to work with tree-ssa
@ 2004-06-22 23:05 Richard Kenner
  2004-06-23 11:42 ` Nathan Sidwell
  0 siblings, 1 reply; 77+ messages in thread
From: Richard Kenner @ 2004-06-22 23:05 UTC (permalink / raw)
  To: nathan; +Cc: gcc-patches

    so it's an accident then? why not just remove it?

I'm not at all convinced it's an "accident".  The GNU C extensions
were never documented, but that doesn't mean that nobody used them.
The code I showed is just a logical consequence of the existance of
those extensions.  I've certainly known that it will work for quite
some time, perhaps as long as 20 years.  There's no way to know how
much code that depends on this is out there.

I'll repeat now what I said a few weeks ago: it's precisely because of
these things already being in GCC that the GNAT project chose GCC to
use as a backend.

In any event, there's no reason to remove this since we can easily support it.

^ permalink raw reply	[flat|nested] 77+ messages in thread
* Re: Patch to allow Ada to work with tree-ssa
@ 2004-06-22 22:18 Richard Kenner
  2004-06-23  1:07 ` Richard Henderson
  0 siblings, 1 reply; 77+ messages in thread
From: Richard Kenner @ 2004-06-22 22:18 UTC (permalink / raw)
  To: rth; +Cc: gcc-patches

    Surely you're applying highest_pow2_factor step-by-step as you walk
    down the components.  Which means that the TYPE_ALIGN is just fine.

No, it's done once at the end.  And TYPE_ALIGN isn't fine, as I said,
because there's no assurance that fields are aligned corresponding to
their type.

    I'm absolutely certain that this *must* change.  For exactly the same
    reason that we added TYPE_SIZE_UNIT, we do not want to be doing pointer
    arithmetic in units other than bytes.

I don't follow.  TYPE_SIZE_UNIT was added because TYPE_SIZE was too large
to represent in an integer.  Doing arithmetic in units *larger* than
bytes doesn't have that problem.

But I agree this needs to change.  Look at all the kludges related to
this in ada/decl.c for example.  Another was added recently as a result
of a reported bug.

I've had a number of ideas to fix this over time, but none I really
liked.  Most of them are no longer applicable in a tree-ssa context,
though.  But this is really a different topic, so we should take it
out of this thread.

    This is wrong.  REALPART_EXPR is not like other gimple operands 
    because (irritatingly) it is an lvalue.  You can take its address.

    It has *exactly* the same semantics as <COMPONENT_REF var real_part>
    or <ARRAY_REF var 0>.  So it should be treated the same way.

OK.

^ permalink raw reply	[flat|nested] 77+ messages in thread
* Re: Patch to allow Ada to work with tree-ssa
@ 2004-06-22 21:30 Richard Kenner
  2004-06-22 22:04 ` Paul Brook
  0 siblings, 1 reply; 77+ messages in thread
From: Richard Kenner @ 2004-06-22 21:30 UTC (permalink / raw)
  To: paul; +Cc: gcc-patches

    Basically what we need is ARRAY_REF (or implicitly via ARRAY_TYPE)
    which allows you to specify the array stride. In C terms this means
    sizeof(a[0]) != (a[1] - a[0]). In fact sizeof(a[0]) may not be
    meaningful if it is and outer reference of a multi-dimensional array.

Well the critical question is whether this is always a constant
or not.  If it's always a constant, then you always have the option
of making up an appropriate ARRAY_TYPE.  If it's a *variable*, then
you don't have the option of getting the value implicitly from the
type and have to put it someplace explicitly in the node.

^ permalink raw reply	[flat|nested] 77+ messages in thread
* Re: Patch to allow Ada to work with tree-ssa
@ 2004-06-22 21:27 Richard Kenner
  2004-06-22 21:29 ` Mark Mitchell
  0 siblings, 1 reply; 77+ messages in thread
From: Richard Kenner @ 2004-06-22 21:27 UTC (permalink / raw)
  To: mark; +Cc: gcc-patches

    RTH has already said he's in favor of this approach, and he's one of
    the tree-ssa folks.

In GIMPLE?

I haven't seen any such statement.

^ permalink raw reply	[flat|nested] 77+ messages in thread
* Re: Patch to allow Ada to work with tree-ssa
@ 2004-06-22 21:10 Richard Kenner
  2004-06-22 21:12 ` Mark Mitchell
  2004-06-22 22:16 ` Daniel Berlin
  0 siblings, 2 replies; 77+ messages in thread
From: Richard Kenner @ 2004-06-22 21:10 UTC (permalink / raw)
  To: mark; +Cc: gcc-patches

    Since Richard Henderson and Zack seem to think it's best, why don't you 
    just create new tree nodes for these variable-length cases?  That seems 
    to be the consensus point of view on how to solve the problem.

Except that the authors of the optimizers haven't weighed in here yet
and they were very much against adding new nodes to GIMPLE, which is
what this would be doing.  Having played with some of that code, I can
tell you that it won't be pleasant to add all the extra cases to
deal with the additional nodes.

Also, I'm told that over on IRC, the Fortran folks have ideas about
what to do with some of the new fields.

I think the memory cost argument in GIMPLE is very weak: only a very
tiny fraction of GIMPLE nodes are ARRAY_REF and COMPONENT_REF.

Your arguments about trees that are permanently kept around at the
GENERIC level seems a far stronger argument and that's why I was thinking
about having a different node for front-end use that corresponds to
the shorter form.

^ permalink raw reply	[flat|nested] 77+ messages in thread
* Re: Patch to allow Ada to work with tree-ssa
@ 2004-06-22 21:07 Richard Kenner
  2004-06-22 21:12 ` Bryce McKinlay
  0 siblings, 1 reply; 77+ messages in thread
From: Richard Kenner @ 2004-06-22 21:07 UTC (permalink / raw)
  To: aph; +Cc: gcc-patches, java

    I'll provide a more detailed diagnosis tomorrow.  It's quite possible,
    of course, that you've revealed a bug in the Java gimplification code.

No, I think it's the case I mentioned in my last message.  If so, not too
bad to fix.

I don't know how to run Java code, though.  Can you tell me the command-line
options I need with the file you provided to see the problem?

^ permalink raw reply	[flat|nested] 77+ messages in thread
* Re: Patch to allow Ada to work with tree-ssa
@ 2004-06-22 21:05 Richard Kenner
  0 siblings, 0 replies; 77+ messages in thread
From: Richard Kenner @ 2004-06-22 21:05 UTC (permalink / raw)
  To: jsm; +Cc: aph, gcc-patches, java

    We have a flag (flag_evaluation_order) for languages to say whether the
    order of evaluation of subexpressions matters (effectively creating two
    dialects of GENERIC).  Java sets this flag, and it should be followed.

And the order is what, in operand number order in the GENERIC tree?

^ permalink raw reply	[flat|nested] 77+ messages in thread
* Re: Patch to allow Ada to work with tree-ssa
@ 2004-06-22 21:01 Richard Kenner
  0 siblings, 0 replies; 77+ messages in thread
From: Richard Kenner @ 2004-06-22 21:01 UTC (permalink / raw)
  To: rth; +Cc: aph, gcc-patches, java, rmathew

    > It seems that something has changed the depth-first, left-to-right
    > parsing of expressions.  Have you any idea what might have caused this?

    I'm betting the changes to gimplify_compound_lval.

Or gimplify_modify_expr.

If it's gimplify_compound_lval, it's going to be a little tricky to do
it the other way around.  You can't gimplify the prefix first because
you need to have the unmodified prefix available to resolve any
PLACEHOLDER_EXPRs in bounds and sizes.

We could certainly copy the prefix, but that would waste memory.

Perhaps another approach would be to make two passes over the indexes
and components.  So we first make one pass to fill in the extra operands,
then gimplify the prefix, then go down and gimplify all the indexes.

If it can be determined that this is the problem, let me know and I'll
implement the approach above.

^ permalink raw reply	[flat|nested] 77+ messages in thread
* Re: Patch to allow Ada to work with tree-ssa
@ 2004-06-22 20:54 Richard Kenner
  2004-06-22 21:06 ` Paul Brook
  2004-06-22 21:37 ` Richard Henderson
  0 siblings, 2 replies; 77+ messages in thread
From: Richard Kenner @ 2004-06-22 20:54 UTC (permalink / raw)
  To: rth; +Cc: gcc-patches

    If we're going to change anything here, I'd prefer that the
    gimplifier handle NULL as an empty statement.  Then we don't
    have to allocate anything or merge anything.

Interesting idea.  Probably worth it, though.

    I should have been more clear.  Fortran has plans to use this
    field for stride different than size.

OK, but array_ref_element_size looks at that field only if it's set.
Before gimplification, it's not and it returns the actual element size.
Are Fortran's plans consistent with that?

    Not really.  There are only two things that highest_pow2_factor is
    going to see given gimple input: a constant or variable times 
    constant.  Which means that you can just as well use the TYPE_ALIGN
    when given a non-constant.

Using TYPE_ALIGN doesn't work because you don't know whether all the fields
in the path are aligned that way.  They might be "bit fields" that are
misaligned.  Before highest_pow2_factor and the MEM_ALIGN addition, we used
to get this wrong a lot.  Now we are very precise.

Also, the whole point of what I did is that highest_pow2_factor *will* see
the multiply!  get_inner_reference will call array_ref_element_size which
will generate the multiplication (in the variable case).

    > Right.  It doesn't seem worth the trouble here.

    Meaning the comment is incorrect.

I'll go back and look at the code, but I think I just copied the comment,
and didn't add it ...

    > Because get_inner_reference doesn't support IMAGPART_EXPR and
    > REALPART_EXPR. It seemed cleaner to break up the two cases since they
    > are handled differently.

    I disagree.  It's just another accessor.  Feed the whole lot to
    expand_expr and you'll get the right answer anyway.

Sure, but by that argument we can allow <PLUS_EXPR <MULT_EXPR ....>> in
GIMPLE!  My point is that REALPART_EXPR and IMAGPART_EXPR have inputs and
outputs that are both scalars, so it would seem more in keeping with
the GIMPLE strategy to not mix them with other operations.

    So you've got a reference a.b.c.d.e in which, say, b is volatile?
    So why are you removing the c.d.e bits of the componentry, so that
    you access more of b than the user intended?

Good point.  I'll have to investigate that again.  If my memory is
correct, this was motivated by a C or C++ testcase, not Ada.

    > I'll have to investigate that: I never heard of list_p.

    Yes you have.  It's the list argument to append_to_statemnt_list.
    Meaning taking a "tree *" in which to put statements is a better
    option than returning a statement list.

Oh!  If you'd said stmt_p, I would have known what you meant.  Yes, I
think you're right: I'll change that.

    No, you don't abort, gimplify_expr aborts.   Just don't provide
    the post queue.

OK.

^ permalink raw reply	[flat|nested] 77+ messages in thread
* Re: Patch to allow Ada to work with tree-ssa
@ 2004-06-22 20:44 Richard Kenner
  2004-06-22 21:03 ` Mark Mitchell
  2004-06-23 20:58 ` Geoffrey Keating
  0 siblings, 2 replies; 77+ messages in thread
From: Richard Kenner @ 2004-06-22 20:44 UTC (permalink / raw)
  To: mark; +Cc: gcc-patches

    However, you've penalized the vastly more common case (100% of the
    cases in ANSI/ISO C89) at the expense of an uncommon case.

That's true in Ada as well, of course.  But, unfortunately, much of
compiler development concentrates on getting the very uncommon cases right.

    That's why you should find another way -- a different tree code, a
    flag in the node indicating how many arguments are in use, or stuff
    the additional arguments into the existing slots by using a TREE_LIST
    in those slots as necessary.

Yes, but what I hear from the tree-ssa folks is that it's absolutely
critical that GIMPLE be as simple as possible, which goes against any
of those methods.  That's the tradeoff here.  If it were permitted to
make GIMPLE be more complex, we likely wouldn't have need the extra
fields in the first place!

^ permalink raw reply	[flat|nested] 77+ messages in thread
* Re: Patch to allow Ada to work with tree-ssa
@ 2004-06-22 20:40 Richard Kenner
  2004-06-22 22:02 ` Nathan Sidwell
  0 siblings, 1 reply; 77+ messages in thread
From: Richard Kenner @ 2004-06-22 20:40 UTC (permalink / raw)
  To: nathan; +Cc: gcc-patches

    > int
    > sub1 (int n)
    > {
    >   struct foo {int arr[n]; int filler : 3; int fld : 4;} x;
    > 
    >   return x.fld;
    > }

    This is not valid C89, C90, or documented as a GNU extension.

That may be, but it's worked on every version of GCC so far ...

^ permalink raw reply	[flat|nested] 77+ messages in thread
* Re: Patch to allow Ada to work with tree-ssa
@ 2004-06-22 20:23 Richard Kenner
  2004-06-22 20:37 ` Joseph S. Myers
  2004-06-23 20:47 ` Geoffrey Keating
  0 siblings, 2 replies; 77+ messages in thread
From: Richard Kenner @ 2004-06-22 20:23 UTC (permalink / raw)
  To: jsm; +Cc: gcc-patches

    Both have increased by a factor of between 21 and 22 in 5742 days.  A
    1% increase every 18 days suffices to explain this.  What we do at -O0
    should not be 20 times as complicated as what GCC 1.27 did at -O0.

Although I'm not arguing in favor of wasting memory, it's also imporant to
look at the typical amounts of memory available at each of those times
and see how it has increased as well.  I'm also not sure that -O0 is
a good comparison point because the amount of data we keep is related
to optimization issues and there's little motivation for have two
different data structures and use one for optimized and the other for
unoptimized code.

^ permalink raw reply	[flat|nested] 77+ messages in thread
* Re: Patch to allow Ada to work with tree-ssa
@ 2004-06-22 19:05 Richard Kenner
  2004-06-22 20:10 ` Joseph S. Myers
  2004-06-22 20:27 ` Andrew Haley
  0 siblings, 2 replies; 77+ messages in thread
From: Richard Kenner @ 2004-06-22 19:05 UTC (permalink / raw)
  To: aph; +Cc: gcc-patches, java

     > I somebody could point out what tree transformation is going wrong, I'll
     > be glad to fix it.

    It seems that something has changed the depth-first, left-to-right
    parsing of expressions.  Have you any idea what might have caused this?

"parsing"?  Did you mean gimplifying?

Indeed a number of things I did might have had the effect of changing
the order in which subtrees are gimplified.  Since I didn't think that
anything depended on that, I didn't pay that much attention to the issue.
If there are places that do depend on that, can you identify them so
that comments can be placed in gimplify.c saying what's order-dependent.

The changes would mostly relate to the order of gimplification of MODIFY_EXPR
and certain compound values, I'd guess.

Can you give an example of an expression that's handled differently?

^ permalink raw reply	[flat|nested] 77+ messages in thread
[parent not found: <10406221359.AA05860@vlsi1.ultra.nyu.edu>]
* Re: Patch to allow Ada to work with tree-ssa
@ 2004-06-22 18:33 Richard Kenner
  0 siblings, 0 replies; 77+ messages in thread
From: Richard Kenner @ 2004-06-22 18:33 UTC (permalink / raw)
  To: aph; +Cc: gcc-patches

    Also, we've got Java regressions.  It seems that something in Kenner's
    patch changes the way that expressions are gimplified.  In my opinion,
    the Java testsuite should also have been run before this was checked
    in.

As I said, I only went as far as my own abilities took me.  I did run the
entire Java library through the compiler and fixed the few problems that
showed up doing that.

Beyond that, I'll need some help since I don't have knowlege of Java and the
reason I checked the patch in is that it would be easier to solicit that help
once it's in the tree than if it were just a private patch.

Note that the things I fixed affect C as well as Ada it's just that it's
very rare to see them in C but quite common in Ada.

^ permalink raw reply	[flat|nested] 77+ messages in thread
* Re: Patch to allow Ada to work with tree-ssa
@ 2004-06-22 18:19 Richard Kenner
  2004-06-22 18:36 ` Nathan Sidwell
  2004-06-22 18:45 ` Mark Mitchell
  0 siblings, 2 replies; 77+ messages in thread
From: Richard Kenner @ 2004-06-22 18:19 UTC (permalink / raw)
  To: mark; +Cc: gcc-patches

    In particular, you've just added an extra entry to ARRAY_REF and
    COMPONENT_REF, making these two common tree nodes bigger.
    (COMPONENT_REF, in particular, is used extensively in C++; every
    access to a class member variable is a COMPONENT_REF.)  These extra
    entries are unnecessary in C and C++, meaning that for GCC's two
    most-used languages you've just increased memory usage with no
    benefit.  If you need some additional stuff for Ada, please find a way
    that doesn't penalize C and C++.

Here's the specific test case for C.  I note that it isn't valid C++,
but I don't know C++ well enough to make a similar case there.  Note
that the proposal involving using an INDIRECT_REF won't work with this
case because it's a bitfield.

int
sub1 (int n)
{
  struct foo {int arr[n]; int filler : 3; int fld : 4;} x;

  return x.fld;
}

^ permalink raw reply	[flat|nested] 77+ messages in thread
* Re: Patch to allow Ada to work with tree-ssa
@ 2004-06-22 17:05 Richard Kenner
  2004-06-22 17:21 ` Andrew Haley
  0 siblings, 1 reply; 77+ messages in thread
From: Richard Kenner @ 2004-06-22 17:05 UTC (permalink / raw)
  To: rmathew; +Cc: gcc-patches, java

    Though I've not been able to fully analyse it, very likely
    this is the patch that is causing 2 new FAILs for libjava
    on i686-pc-linux-gnu. (If not, I apologise in advance.)

Could well be. 
        
    The testcase is "libjava/testsuite/libjava.lang/err6.java"
    and is reproduced here for your reference:

Could I ask for somebody's help here?  I don't even know the Java language,
let alone the Java front end.

I somebody could point out what tree transformation is going wrong, I'll
be glad to fix it.

Thanks.

^ permalink raw reply	[flat|nested] 77+ messages in thread
* Re: Patch to allow Ada to work with tree-ssa
@ 2004-06-22 16:34 Richard Kenner
  0 siblings, 0 replies; 77+ messages in thread
From: Richard Kenner @ 2004-06-22 16:34 UTC (permalink / raw)
  To: pinskia; +Cc: gcc-patches

    In fact I had a patch for tree-unnested to get rid of the impliciant
    uses for OFFSET, see
    <http://gcc.gnu.org/ml/gcc-patches/2004-05/msg00373.html> Which fixed
    the problem a different way.

We discussed this approach and I also mentioned it in my message of yesterday
morning.  The problem is that you are taking the address of things that are
not necessarily addressable.

^ permalink raw reply	[flat|nested] 77+ messages in thread
* Re: Patch to allow Ada to work with tree-ssa
@ 2004-06-22 16:33 Richard Kenner
  2004-06-22 17:46 ` Mark Mitchell
  0 siblings, 1 reply; 77+ messages in thread
From: Richard Kenner @ 2004-06-22 16:33 UTC (permalink / raw)
  To: mark; +Cc: gcc-patches

    In particular, you've just added an extra entry to ARRAY_REF and 
    COMPONENT_REF, making these two common tree nodes bigger.  
    (COMPONENT_REF, in particular, is used extensively in C++; every access 
    to a class member variable is a COMPONENT_REF.)  These extra entries are 
    unnecessary in C and C++, meaning that for GCC's two most-used languages 
    you've just increased memory usage with no benefit.  If you need
    some additional stuff for Ada, please find a way that doesn't penalize
    C and C++.

I can show you a GNU C program that needs them as well.  We support
variable-sized types.

This issue was discussed extensively on the GCC list and nobody had a
better idea as to how to do it.  Moreover, I sent email yesterday morning
saying what my plans were and nobody objected.

    Furthermore, you didn't update the c-tree.texi documentation.  

That's a C-specific file: these are language-independent nodes.
I did document them in tree.def.

    You also didn't add accessor macros for these additional operands, so
    the only place to look is at the documentation you added in tree.def,
    which suggests that these additional operands are redundant; 

I added accessor *functions* for each of these:
	array_ref_low_bound,
	array_ref_element_size, and
	component_ref_field_offset
They are supposed to be used (and are used) whenever those fields
are needed.

We don't have accessor macros for any other fields of references or
expressions, so I didn't add them for this.  I would be in favor of
adding accesor macros for all expressions (e.g. MODIFY_EXPR_RHS) to
include these, but I think it would be very peculiar to have an
accessor macro for operands 2 and 3 of an ARRAY_REF when we don't have
them for operands 0 and 1!  That's why I didn't add them.

    for example, the third operand in a COMPONENT_REF is defined in terms
    of the DECL_FIELD_OFFSET of the second operand; if that's true, why do
    we need to have it there explicitly?  Presumably, this has something
    to do with variable-sized types, but the documentation does not say
    what that is.

I'm not sure what you want and where.  The nodes are defined even for
fixed records.

As to getting the data from DECL_FIELD_OFFSET (or TYPE_MIN_VALUE), that was
my original plan since I also didn't like the idea of of increasing the size
of the node.  But *lots* of people were very much against that idea,
including Diego, RTH, Jeff, and some I can't remember now.  I still was
hoping for an approach like that, but then I realized that PLACEHOLDER_EXPR
makes it *not* redundant in any case, so I did what others wanted me to
do, which is perhaps this approach.

    If that's what this is about, then I suggest you find a way to make
    these nodes bigger in Ada than it is in C/C++ and only look for the
    additional fields there, or have a flag in ARRAY_REF that indicates
    whether these additional fields are present.

It's not C vs. Ada but fixed vs. variable.  Most arrays and components in Ada
are fixed size, just like in C.  It's more an issue of *frequency*.  In C and
C++, variable-sized stuff is quite rare, while in Ada it's more common.

We don't have a mechanism to have a tree code be of two different sizes
depending on the setting of a flag, so we'd have to add one.  We could have
two different tree codes, but that would complicate the optimizers and is
exactly what this mechanism is trying to avoid.

    Please revert this patch until we've got consensus here.

I don't want to do that.  It's a large patch and I have further changes that
I'll be making on top of it and reverting it at this point would bring my
work to a stop for an indefinite amount of time.

We *had* concensus.  This approach was discussed *weeks* ago and nobody
objected, including you.  I wouldn't have spent weeks implementing and
testing this if I didn't feel everybody agreed on it.

Look, for example, at http://gcc.gnu.org/ml/gcc/2004-06/msg00459.html
That was over two weeks ago and was the time to object.

Yes, it adds some more memory utilization, and yes, that's not good.  But
it's very small. According to Nathan and Zack's paper, expression nodes in
total amount to 19% of memory utilization in C++ programs.

An expression node has quite a large number of fields.  The common part is
four words.  The expression adds another four words plus the operands.  So
ARRAY_REF used to be 12 words and is now 14, an increase of 17%.
COMPONENT_REF used to be 12 and is now 13, an increase of 8%.  I don't know
how common those nodes are in expressions, but in GIMPLE, almost half of all
expr nodes are MODIFY_EXPR.

Let's make the very pessimistic assumption that COMPONENT_REF are half of the
remaining nodes and ARRAY_REF are half of what's left.  So 25% of expr nodes
grow 8% and 12% grow 17%.  That's an increase of 4% in memory for expr nodes.
Since they are 19% of all nodes, that's an overall memory increase of under
1%.  I think we can live with that.

Nathan and Zack are working on redoing the tree structure anyway so this can
get taken care of then.

If there is consensus after discussion that this patch is bad, I will, of
course, revert it, but I'd *much* rather use it as a base and make
improvements to it as needed, so progress can go forward, not backward.

^ permalink raw reply	[flat|nested] 77+ messages in thread
* Patch to allow Ada to work with tree-ssa
@ 2004-06-22  7:05 Richard Kenner
  2004-06-22  7:29 ` Mark Mitchell
                   ` (3 more replies)
  0 siblings, 4 replies; 77+ messages in thread
From: Richard Kenner @ 2004-06-22  7:05 UTC (permalink / raw)
  To: gcc-patches

This is the patch I spoke about this morning.  Much of it is mechanical, but
a good part is not.

I've been working on an x86_64 target.  It's at the point where all languages
except Ada (there's still some work to do there, as I said) bootstrap,
everything builds, there are no C regressions and only the C++ regression I
mentioned this morning.

At this point, I felt it best to get it out of my tree and into the head
where people can bash away at it and also help to get any remaining problems
(and I'm sure there will be) fixed.  There are also a few things that need to
be tweaked a bit, but that too will easier once it's checked in.  This patch
is too large and affects too many files to keep locally for too much longer,
but too small to justify a branch.

I think everybody agrees on the general overview of what I did and it's
easier to deal with details now that it's checked in.  I'll be available to
take care of any problems it causes.

I'm sorry in advance if this somewhat non-standard approach causes problems,
but I think it's the best approach at this point.

2004-06-21  Richard Kenner  <kenner@vlsi1.ultra.nyu.edu>

	* alias.c (adjust_offset_for_component_ref): Use
	component_ref_field_offset.
	* c-decl.c (build_array_declarator): Add news args for ARRAY_REF.
	* c-gimplify.c (gimplify_expr_stmt): Use alloc_stmt_list.
	(gimplify_decl_stmt): Call gimplify_type_sizes for type.
	For decl, call gimplify_one_sizepos and use statement list.
	(gimplify_compound_literal_expr): New arg PRE_P.
	Add statement to PRE_P list and return DECL.
	(c_gimplify_expr, case COMPOUND_LITERAL_EXPR): Add arg to
	gimplify_compound_literal_expr.
	* c-tree.h (getdecls): Deleted.
	* c-typeck.c (build_component_ref): Add operand for COMPONENT_REF.
	(build_array_ref): Add two operands for ARRAY_REF.
	(build_unary_op): Set TREE_INVARIANT and TREE_CONSTANT for
	COMPOUND_LITERAL_EXPR.
	* coverage.c (tree_coverage_counter_ref): Add new operands
	for ARRAY_REF.
	* emit-rtl.c (component_ref_for_mem_expr): Add new operand
	for COMPONENT_REF.
	(set_mem_attributes_minus_bitpos): Use array_ref_low_bound
	and array_ref_element_size.
	(widen_memory_access):Use component_ref_field_offset.
	* explow.c (update_nonlocal_goto_save_area): Add two operands
	for ARRAY_REF.
	* expr.c (array_ref_element_size, array_ref_low_bound): New functions.
	(component_ref_field_offset): Likewise.
	(get_inner_reference): Use them.
	(expand_expr_real_1, case ARRAY_REF): Use array_ref_low_bound.
	* fold-const.c (fold, case EQ_EXPR): Properly handle DECL_SIZE.
	(fold_read_from_constant_string): Use array_ref_low_bound.
	Verify that result is a character type.
	(build_fold_indirect_ref): Add two operands for ARRAY_REF.
	* function.c (expand_function_start): Likewise.
	* gimple-low.c (expand_var_p): Delete duplicated line.
	* gimplify.c: Add static decls for local functions.
	(cgraph.h): Now included.
	(create_tmp_var): Remove check for ARRAY_TYPE.
	(copy_if_shared_r): Look at bounds and sizes of types.
	(build_and_jump): Return alloc_stmt_list instead of build_empty_stmt.
	(gimplify_exit_expr, shortcut_cond_expr): Likewise.
	(gimplify_save_expr, gimple_push_cleanup): Likewise.
	(gimplify_init_constructor): Likewise.
	WANT_VALUE now bool.
	If empty list with no result wanted, return GS_UNHANDLED.
	Add additional operands for ARRAY_REF and COMPONENT_REF.
	(canonicalize_component_ref): Convert to &array[L].
	(gimplify_array_ref_to_plus): Use array_ref_element_size and
	array_ref_lower_bound.
	(build_addr_expr_with_type, build_addr_expr): New functions.
	(gimplify_compound_lval): WANT_LVALUE now bool.
	Major rework to allow handle_component_p and initialize and
	gimplify new operands for ARRAY_REF, ARRAY_RANGE_REF, and
	COMPONENT_REF.
	(gimplify_array_ref): Deleted.
	(gimplify_self_mod_expr): WANT_VALUE now bool.
	(gimplify_modify_expr): Gimplify to_p and from_p later.
	Factor out code into gimplify_modify_expr_rhs and call twice.
	Move variable-size code earlier and handle PLACEHOLDER_EXPR.
	(gimplify_modify_expr_rhs, gimplify_variable_sized_compare): New fns.
	(gimplify_addr_expr, case VIEW_CONVERT_EXPR): New case.
	(gimplify_expr, case ARRAY_REF): Delete special case.
	Instead handle like COMPONENT_REF; also do ARRAY_RANGE_REF,
	IMAGPART, and REALPART the same way.
	(gimplify_expr, case VIEW_CONVERT_EXPR): New case.
	(gimplify_expr): Call gimplify_variable_sized_compare if applicable.
	Call alloc_stmt_list instead of build_empty_stmt.
	Deal with _REF that's volatile.
	(gimplify_type_sizes, gimplify_one_sizepos): New functions.
	(unshare_body, unvisit_body): New functions.
	(gimplify_body): Call them.
	* stmt.c (expand_stack_alloc): Don't expand TYPE_MAX_VALUE.
	* stor-layout.c (get_pending_sizes): Don't change SAVE_EXPR_CONTEXT.
	* tree-alias-common.c (get_alias_var): Also skip ARRAY_RANGE_REF.
	* tree-cfg.c (tree_node_can_be_shared): Treat ARRAY_RANGE_REF
	like ARRAY_REF.
	(verify_expr, case ADDR_EXPR): Use handled_component_p.
	* tree-dfa.c (get_virtual_var): Likewise.
	* tree-dump.c (dequeue_and_dump, case COMPONENT_REF, ARRAY_REF):
	New cases to dump new operands; likewise for ARRAY_RANGE_REF.
	* tree-eh.c (tree_could_trap, case ARRAY_RANGE_REF): Like ARRAY_REF.
	* tree-gimple.c (is_gimple_addr_expr_arg): Add ARRAY_RANGE_REF
	and INDIRECT_REF.
	(get_base_address): Use handled_component_p.
	* tree-gimple.h (gimplify_type_sizes, gimplify_one_sizepos): New.
	* tree-inline.c (walk_tree): Walk more things for types and decls.
	* tree-mudflap.c (mf_build_check_statement_for): Add new operands
	for ARRAY_REF and COMPONENT_REF.
	(mx_xform_derefs_1): Clean up usage of decl sizes.
	* tree-nested.c (build_addr): Use handled_component_p.
	(walk_stmts, case CATCH_EXPR): Add missing "break".
	(get_static_chain, get_frame_field): Add new operand for COMPONENT_REF.
	(finalize_nesting_tree_1): Likewise.
	(convert_nonlocal_reference, case ARRAY_RANGE_REF): Like ARRAY_REF
	and process additional operands.
	(convert_local_reference): Likewise.
	* tree-outof-ssa.c (discover_nonconstant_array_refs_r): Treat
	ARRAY_RANGE_REF similarly to ARRAY_REF.
	* tree-pretty-print.c (dump_generic_node, case QUAL_UNION_TYPE): Handle
	like RECORD_TYPE.
	(dump_generic_node, case COMPONENT_REF): Print offset operand.
	(dump_generic_node, case ARRAY_RANGE_REF): Treat like ARRAY_REF
	and print lower bound and element size for both.
	(op_prio, case ARRAY_RANGE_REF): Like ARRAY_REF.
	* tree-sra.c (csc_build_component_ref): Add new operand.
	(scalarize_call_expr): Use get_base_address.
	* tree-ssa-ccp.c (widen_bitfield): Clean up size handling.
	(maybe_fold_offset_to_array_ref): Rework to handle input having an
	ARRAY_REF, refine handling of lower bound, and add new operands
	for ARRAY_REF.
	(maybe_fold_to_component_ref): Add new operand for COMPONENT_REF.
	(maybe_fold_stmt_indirect): Only fold *&B to B if types match.
	(maybe_fold_stmt_addition): Only handle constant lower bound.
	* tree-ssa-operands.c (get_expr_operands): Minor rearrangements.
	Treat ARRAY_REF and ARRAY_RANGE_REF the same; look at extra operands.
	Look at new offset operand of COMPONENT_REF.
	* tree-ssa.c (set_is_used): Use handled_component_p.
	* tree.c (substitute_in_expr, case COMPONENT_REF): Add new operand.
	(stabilize_reference, case COMPONENT_REF): Likewise.
	(stabilize_reference, case ARRAY_RANGE_REF, ARRAY_REF): Similarly.
	(recompute_tree_invariant_for_addr_expr): Completely rework to
	be more precise.  Also set TREE_SIDE_EFFECTS.
	(build1_stat, case ARRAY_EXPR): Don't handle TREE_SIDE_EFFECTS here.
	(build2_stat, build3_stat, build4_stat): For references,
	propagate TREE_THIS_VOLATILE.
	(get_unwidened): Add new operand for COMPONENT_REF.
	(get_narrower): Likewise; use host_integerp for DECL_SIZE.
	* tree.def (COMPONENT_REF): Add new operand.
	(ARRAY_REF, ARRAY_RANGE_REF): Add two new operands.
	* tree.h (array_ref_element_size, array_ref_low_bound): New decls.
	(component_ref_field_offset): Likewise.
	* config/alpha/alpha.c (alpha_va_start): Add new op for COMPONENT_REF.
	(alpha_gimplify_va_arg): Likewise.
	* config/i386/i386.c (ix86_va_start, ix86_gimplify_va_arg): Likewise.
	* config/i860/i860.c (i860_va_start, i860_va_arg): Likewise.
	* config/iq2000/iq2000.c (iq2000_va_arg): Likewise.
	* config/mips/mips.c (mips_va_start, mips_va_arg): Likewise.
	* config/rs6000/rs6000.c (rs6000_va_start, rs6000_gimplify_va_arg):
	Likewise.
	* config/s390/s390.c (s390_va_start, s390_gimplify_va_arg): Likewise.
	* config/sh/sh.c (sh_va_start, sh_va_arg): Likewise.
	* config/stormy16/stormy16.c (xstormy1_expand_builin_va_start):
	Likewise.
	(xstormy16_expand_builtin_va_arg): Likewise.
	* config/xtensa/xtensa.c (xtensa_va_start, xtensa_va_arg): Likewise.

	* cp/call.c (build_vfield_ref): Add new operand for COMPONENT_REF.
	(build_new_method_call): Likewise.
	* cp/decl.c (local_variable_p_walkfn): Don't walk into types.
	* cp/decl2.c (grok_array_decl): Add new operands for ARRAY_REF.
	(build_anon_union_vars): Add new operand for COMPONENT_REF.
	* cp/init.c (buld_new): Add new operand for ARRAY_REF.
	* cp/method.c (do_build_copy_constructor): New op for COMPONENT_REF.
	(do_build_assign_ref): Likewise.
	* cp/parser.c (cp_parser_direct_new_declarator): Add new operands
	for ARRAY_REF.
	(cp_parser_direct_declarator): Likewise.
	* cp/pt.c (tsubst): Likewise.
	(tsubst_copy, tsubst_copy_and_build): Likewise; also add new operand
 	for COMPONENT_REF.
	* cp/semantics.c (finish_non_static_data_member): Add new operand
	for COMPONENT_REF.
	* cp/typeck.c (build_class_member_access_expr): Likewise.
	(build_class_member_access_expr, finish_class_member_access_expr):
	Likewise.
	(build_ptrmemfunc_access_expr): Likewise.
	(build_array_ref): Add new operands for ARRAY_REF.
	* cp/typeck2.c (split_nonconstant_init_1): Likewise; COMPONENT_REF too.
	* cp/tree.c (count_trees_r, no_linkage_helper): Don't walk in types.
	
	* fortran/f95-lang.c (LANG_HOOKS_GIMPLE_BEFORE_INLINING): Deleted.
	* fortran/trans-array.c (gfc_conv_descriptor_data): Add operand
	for COMPONENT_REF.
	(gfc_conv_descriptor_offset, gfc_conv_descriptor_dtype): Likewise.
	(gfc_conv_descriptor_dimension, gfc_conv_descriptor_stride): Likewise.
	(gfc_conv_descriptor_lbound, gfc_conv_descriptor_ubound): Likewise.
	* fortran/trans-common.c (create_common): Likewise.
	* fortran/trans-expr.c (gfc_conv_component_ref): Likewise.
	* fortran/trans-io.c (set_parameter_value): Likewise.
	(set_parameter_ref, set_string, set_flag, io_result): Likewise.
	(transfer_expr): Likewise.
	* fortran/trans-decl.c (gfc_trans_auto_character_variable):
	Set up to get DECL_SIZE and DECL_SIZE_UNIT gimplified.
	(gfc_simplify_function): New function.
	(gfc_generate_function-code): Properly handle nested functions.
	* fortran/trans.c (gfc_build_array_ref): Add two new operands
	for ARRAY_REF.

	* java/class.c (build_class_ref): Add new operand for COMPONENT_REF.
	(build_static_field_ref): Likewise and add new operands for ARRAY_REF.
	* java/constants.c (build_ref_from_constant_pool): Likewise.
	* java/expr.c (build_java_array_length_access): Likewise.
	(build_get_class, build_field_ref, build_known_method_ref): Likewise.
	(invoke_build_dtable, build_invokevirtual): Likewise.
	(build_invokeinterface, java_expand_expr): Likewise.
	(emit_init_test_initialization): Likewise.
	* java/java-gimplify.c (java_gimplify_new_array_init): Likewise.
	* java/parse.y (make_qualifed_name, build_array_ref): Likewise.
	
	* objc/objc-act.c (generate_static_references): Add additional
	operands to ARRAY_REF.
	(generate_strings, build_method_prototype_list_template): Likewise.
	(generate_protocol_list): Likewise.

*** alias.c	15 Jun 2004 18:02:07 -0000	1.229
--- alias.c	21 Jun 2004 22:49:42 -0000
*************** adjust_offset_for_component_ref (tree x,
*** 2016,2024 ****
    do
      {
        tree field = TREE_OPERAND (x, 1);
  
!       if (! host_integerp (DECL_FIELD_OFFSET (field), 1))
  	return NULL_RTX;
!       ioffset += (tree_low_cst (DECL_FIELD_OFFSET (field), 1)
  		  + (tree_low_cst (DECL_FIELD_BIT_OFFSET (field), 1)
  		     / BITS_PER_UNIT));
--- 2016,2025 ----
    do
      {
+       tree offset = component_ref_field_offset (x);
        tree field = TREE_OPERAND (x, 1);
  
!       if (! host_integerp (offset, 1))
  	return NULL_RTX;
!       ioffset += (tree_low_cst (offset, 1)
  		  + (tree_low_cst (DECL_FIELD_BIT_OFFSET (field), 1)
  		     / BITS_PER_UNIT));
*** c-decl.c	20 Jun 2004 10:09:56 -0000	1.512
--- c-decl.c	21 Jun 2004 22:49:47 -0000
*************** build_array_declarator (tree expr, tree 
*** 2509,2513 ****
  {
    tree decl;
!   decl = build_nt (ARRAY_REF, NULL_TREE, expr);
    TREE_TYPE (decl) = quals;
    TREE_STATIC (decl) = (static_p ? 1 : 0);
--- 2509,2513 ----
  {
    tree decl;
!   decl = build_nt (ARRAY_REF, NULL_TREE, expr, NULL_TREE, NULL_TREE);
    TREE_TYPE (decl) = quals;
    TREE_STATIC (decl) = (static_p ? 1 : 0);
*** c-gimplify.c	20 Jun 2004 17:16:24 -0000	2.14
--- c-gimplify.c	21 Jun 2004 22:49:47 -0000
*************** gimplify_expr_stmt (tree *stmt_p)
*** 244,248 ****
  
    if (stmt == NULL_TREE)
!     stmt = build_empty_stmt ();
  
    *stmt_p = stmt;
--- 244,248 ----
  
    if (stmt == NULL_TREE)
!     stmt = alloc_stmt_list ();
  
    *stmt_p = stmt;
*************** gimplify_decl_stmt (tree *stmt_p)
*** 487,492 ****
    tree stmt = *stmt_p;
    tree decl = DECL_STMT_DECL (stmt);
-   tree pre = NULL_TREE;
-   tree post = NULL_TREE;
  
    if (TREE_TYPE (decl) == error_mark_node)
--- 487,490 ----
*************** gimplify_decl_stmt (tree *stmt_p)
*** 497,532 ****
      
    if (TREE_CODE (decl) == TYPE_DECL)
!     {
!       tree type = TREE_TYPE (decl);
!       if (TYPE_SIZE_UNIT (type)
!           && !TREE_CONSTANT (TYPE_SIZE_UNIT (type)))
!         {
!           /* This is a variable-sized array type.  Simplify its size.  */
!           tree temp = TYPE_SIZE_UNIT (type);
!           gimplify_expr (&temp, &pre, &post, is_gimple_val, fb_rvalue);
!         }
!     }
  
!   if (TREE_CODE (decl) == VAR_DECL && !DECL_EXTERNAL (decl))
      {
        tree init = DECL_INITIAL (decl);
  
        if (!TREE_CONSTANT (DECL_SIZE (decl)))
  	{
- 	  tree pt_type = build_pointer_type (TREE_TYPE (decl));
- 	  tree alloc, size;
- 
  	  /* This is a variable-sized decl.  Simplify its size and mark it
  	     for deferred expansion.  Note that mudflap depends on the format
  	     of the emitted code: see mx_register_decls().  */
  
! 	  size = get_initialized_tmp_var (DECL_SIZE_UNIT (decl), &pre, &post);
  	  DECL_DEFER_OUTPUT (decl) = 1;
- 	  alloc = build_function_call_expr
- 	    (implicit_built_in_decls[BUILT_IN_STACK_ALLOC],
- 	     tree_cons (NULL_TREE,
- 			build1 (ADDR_EXPR, pt_type, decl),
- 			tree_cons (NULL_TREE, size, NULL_TREE)));
- 	  append_to_compound_expr (alloc, &pre);
  	}
  
--- 495,526 ----
      
    if (TREE_CODE (decl) == TYPE_DECL)
!     *stmt_p = gimplify_type_sizes (TREE_TYPE (decl));
  
!   else if (TREE_CODE (decl) == VAR_DECL && !DECL_EXTERNAL (decl))
      {
        tree init = DECL_INITIAL (decl);
  
+       *stmt_p = NULL_TREE;
+       gimplify_one_sizepos (&DECL_SIZE (decl), stmt_p);
+       gimplify_one_sizepos (&DECL_SIZE_UNIT (decl), stmt_p);
+ 
        if (!TREE_CONSTANT (DECL_SIZE (decl)))
  	{
  	  /* This is a variable-sized decl.  Simplify its size and mark it
  	     for deferred expansion.  Note that mudflap depends on the format
  	     of the emitted code: see mx_register_decls().  */
  
! 	  tree pt_type = build_pointer_type (TREE_TYPE (decl));
! 	  tree alloc_stmt
! 	    = (build_function_call_expr
! 	       (implicit_built_in_decls[BUILT_IN_STACK_ALLOC],
! 		tree_cons (NULL_TREE,
! 			   build1 (ADDR_EXPR, pt_type, decl),
! 			   tree_cons (NULL_TREE, DECL_SIZE_UNIT (decl),
! 				      NULL_TREE))));
! 
! 	  gimplify_stmt (&alloc_stmt);
! 	  append_to_statement_list(alloc_stmt, stmt_p);
  	  DECL_DEFER_OUTPUT (decl) = 1;
  	}
  
*************** gimplify_decl_stmt (tree *stmt_p)
*** 543,554 ****
  	      DECL_INITIAL (decl) = NULL_TREE;
  	      init = build (MODIFY_EXPR, void_type_node, decl, init);
! 	      append_to_compound_expr (init, &pre);
  	    }
  	  else
! 	    {
! 	      /* We must still examine initializers for static variables
! 		 as they may contain a label address.  */
! 	      walk_tree (&init, force_labels_r, NULL, NULL);
! 	    }
  	}
  
--- 537,547 ----
  	      DECL_INITIAL (decl) = NULL_TREE;
  	      init = build (MODIFY_EXPR, void_type_node, decl, init);
! 	      gimplify_stmt (&init);
! 	      append_to_statement_list (init, stmt_p);
  	    }
  	  else
! 	    /* We must still examine initializers for static variables
! 	       as they may contain a label address.  */
! 	    walk_tree (&init, force_labels_r, NULL, NULL);
  	}
  
*************** gimplify_decl_stmt (tree *stmt_p)
*** 559,566 ****
  	gimple_add_tmp_var (decl);
      }
  
!   append_to_compound_expr (post, &pre);
!   *stmt_p = pre;
!   return GS_OK;
  }
  
--- 552,559 ----
  	gimple_add_tmp_var (decl);
      }
+   else
+     *stmt_p = alloc_stmt_list ();
  
!   return GS_ALL_DONE;
  }
  
*************** gimplify_decl_stmt (tree *stmt_p)
*** 572,576 ****
  
  static enum gimplify_status
! gimplify_compound_literal_expr (tree *expr_p)
  {
    tree decl_s = COMPOUND_LITERAL_EXPR_DECL_STMT (*expr_p);
--- 565,569 ----
  
  static enum gimplify_status
! gimplify_compound_literal_expr (tree *expr_p, tree *pre_p)
  {
    tree decl_s = COMPOUND_LITERAL_EXPR_DECL_STMT (*expr_p);
*************** gimplify_compound_literal_expr (tree *ex
*** 584,588 ****
  
    gimplify_decl_stmt (&decl_s);
!   *expr_p = decl_s ? decl_s : decl;
    return GS_OK;
  }
--- 577,582 ----
  
    gimplify_decl_stmt (&decl_s);
!   append_to_statement_list (decl_s, pre_p);
!   *expr_p = decl;
    return GS_OK;
  }
*************** c_gimplify_expr (tree *expr_p, tree *pre
*** 598,602 ****
      {
      case COMPOUND_LITERAL_EXPR:
!       return gimplify_compound_literal_expr (expr_p);
  
      case FOR_STMT:
--- 592,596 ----
      {
      case COMPOUND_LITERAL_EXPR:
!       return gimplify_compound_literal_expr (expr_p, pre_p);
  
      case FOR_STMT:
*** c-tree.h	21 Jun 2004 09:15:20 -0000	1.154
--- c-tree.h	21 Jun 2004 22:49:49 -0000
*************** extern int c_in_case_stmt;
*** 148,152 ****
  
  extern int global_bindings_p (void);
- extern tree getdecls (void);
  extern void push_scope (void);
  extern tree pop_scope (void);
--- 148,151 ----
*** c-typeck.c	21 Jun 2004 09:15:20 -0000	1.323
--- c-typeck.c	21 Jun 2004 22:49:52 -0000
*************** default_function_array_conversion (tree 
*** 1227,1234 ****
        if (TREE_CODE (exp) == VAR_DECL)
  	{
! 	  /* ??? This is not really quite correct
! 	     in that the type of the operand of ADDR_EXPR
! 	     is not the target type of the type of the ADDR_EXPR itself.
! 	     Question is, can this lossage be avoided?  */
  	  adr = build1 (ADDR_EXPR, ptrtype, exp);
  	  if (!c_mark_addressable (exp))
--- 1227,1234 ----
        if (TREE_CODE (exp) == VAR_DECL)
  	{
! 	  /* We are making an ADDR_EXPR of ptrtype.  This is a valid
! 	     ADDR_EXPR because it's the best way of representing what
! 	     happens in C when we take the address of an array and place
! 	     it in a pointer to the element type.  */
  	  adr = build1 (ADDR_EXPR, ptrtype, exp);
  	  if (!c_mark_addressable (exp))
*************** build_component_ref (tree datum, tree co
*** 1488,1492 ****
  	    return error_mark_node;
  
! 	  ref = build (COMPONENT_REF, TREE_TYPE (subdatum), datum, subdatum);
  	  if (TREE_READONLY (datum) || TREE_READONLY (subdatum))
  	    TREE_READONLY (ref) = 1;
--- 1488,1493 ----
  	    return error_mark_node;
  
! 	  ref = build (COMPONENT_REF, TREE_TYPE (subdatum), datum, subdatum,
! 		       NULL_TREE);
  	  if (TREE_READONLY (datum) || TREE_READONLY (subdatum))
  	    TREE_READONLY (ref) = 1;
*************** build_array_ref (tree array, tree index)
*** 1641,1645 ****
  
        type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (array)));
!       rval = build (ARRAY_REF, type, array, index);
        /* Array ref is const/volatile if the array elements are
           or if the array is.  */
--- 1642,1646 ----
  
        type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (array)));
!       rval = build (ARRAY_REF, type, array, index, NULL_TREE, NULL_TREE);
        /* Array ref is const/volatile if the array elements are
           or if the array is.  */
*************** build_unary_op (enum tree_code code, tre
*** 2567,2570 ****
--- 2568,2574 ----
  	  addr = build1 (code, argtype, arg);
  
+ 	if (TREE_CODE (arg) == COMPOUND_LITERAL_EXPR)
+ 	  TREE_INVARIANT (addr) = TREE_CONSTANT (addr) = 1;
+ 
  	return addr;
        }
*** coverage.c	16 Jun 2004 07:25:52 -0000	1.36
--- coverage.c	21 Jun 2004 22:49:56 -0000
*************** tree
*** 429,433 ****
  tree_coverage_counter_ref (unsigned counter, unsigned no)
  {
!   tree t;
  
    if (no >= fn_n_ctrs[counter] - fn_b_ctrs[counter])
--- 429,433 ----
  tree_coverage_counter_ref (unsigned counter, unsigned no)
  {
!   tree domain_type = TYPE_DOMAIN (TREE_TYPE (tree_ctr_tables[counter]));
  
    if (no >= fn_n_ctrs[counter] - fn_b_ctrs[counter])
*************** tree_coverage_counter_ref (unsigned coun
*** 436,442 ****
  
    /* "no" here is an array index, scaled to bytes later.  */
!   t = build (ARRAY_REF, GCOV_TYPE_NODE, tree_ctr_tables[counter],
! 	     build_int_2 (no, 0));
!   return t;
  }
  \f
--- 436,444 ----
  
    /* "no" here is an array index, scaled to bytes later.  */
!   return build (ARRAY_REF, GCOV_TYPE_NODE, tree_ctr_tables[counter],
! 		fold_convert (domain_type, build_int_2 (no, 0)),
! 		TYPE_MIN_VALUE (domain_type),
! 		size_binop (EXACT_DIV_EXPR, TYPE_SIZE_UNIT (GCOV_TYPE_NODE),
! 			    size_int (TYPE_ALIGN (GCOV_TYPE_NODE))));
  }
  \f
*** emit-rtl.c	18 Jun 2004 07:33:06 -0000	1.395
--- emit-rtl.c	21 Jun 2004 22:49:59 -0000
*************** component_ref_for_mem_expr (tree ref)
*** 1461,1466 ****
      return ref;
    else
!     return build (COMPONENT_REF, TREE_TYPE (ref), inner,
! 		  TREE_OPERAND (ref, 1));
  }
  
--- 1461,1466 ----
      return ref;
    else
!     return build (COMPONENT_REF, TREE_TYPE (ref), inner, TREE_OPERAND (ref, 1),
! 		  NULL_TREE);
  }
  
*************** set_mem_attributes_minus_bitpos (rtx ref
*** 1626,1651 ****
  	    {
  	      tree index = TREE_OPERAND (t2, 1);
! 	      tree array = TREE_OPERAND (t2, 0);
! 	      tree domain = TYPE_DOMAIN (TREE_TYPE (array));
! 	      tree low_bound = (domain ? TYPE_MIN_VALUE (domain) : 0);
! 	      tree unit_size = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (array)));
  
  	      /* We assume all arrays have sizes that are a multiple of a byte.
  		 First subtract the lower bound, if any, in the type of the
! 		 index, then convert to sizetype and multiply by the size of the
! 		 array element.  */
! 	      if (low_bound != 0 && ! integer_zerop (low_bound))
  		index = fold (build (MINUS_EXPR, TREE_TYPE (index),
  				     index, low_bound));
  
! 	      /* If the index has a self-referential type, instantiate it;
! 		 likewise for the component size.  */
! 	      index = SUBSTITUTE_PLACEHOLDER_IN_EXPR (index, t2);
! 	      unit_size = SUBSTITUTE_PLACEHOLDER_IN_EXPR (unit_size, array);
! 	      off_tree
! 		= fold (build (PLUS_EXPR, sizetype,
! 			       fold (build (MULT_EXPR, sizetype,
! 					    index, unit_size)),
! 			       off_tree));
  	      t2 = TREE_OPERAND (t2, 0);
  	    }
--- 1626,1645 ----
  	    {
  	      tree index = TREE_OPERAND (t2, 1);
! 	      tree low_bound = array_ref_low_bound (t2);
! 	      tree unit_size = array_ref_element_size (t2);
  
  	      /* We assume all arrays have sizes that are a multiple of a byte.
  		 First subtract the lower bound, if any, in the type of the
! 		 index, then convert to sizetype and multiply by the size of
! 		 the array element.  */
! 	      if (! integer_zerop (low_bound))
  		index = fold (build (MINUS_EXPR, TREE_TYPE (index),
  				     index, low_bound));
  
! 	      off_tree = size_binop (PLUS_EXPR,
! 				     size_binop (MULT_EXPR, convert (sizetype,
! 								     index),
! 						 unit_size),
! 				     off_tree);
  	      t2 = TREE_OPERAND (t2, 0);
  	    }
*************** widen_memory_access (rtx memref, enum ma
*** 2043,2046 ****
--- 2037,2041 ----
  	{
  	  tree field = TREE_OPERAND (expr, 1);
+ 	  tree offset = component_ref_field_offset (expr);
  
  	  if (! DECL_SIZE_UNIT (field))
*************** widen_memory_access (rtx memref, enum ma
*** 2057,2061 ****
  	    break;
  
! 	  if (! host_integerp (DECL_FIELD_OFFSET (field), 1))
  	    {
  	      expr = NULL_TREE;
--- 2052,2056 ----
  	    break;
  
! 	  if (! host_integerp (offset, 1))
  	    {
  	      expr = NULL_TREE;
*************** widen_memory_access (rtx memref, enum ma
*** 2064,2071 ****
  
  	  expr = TREE_OPERAND (expr, 0);
! 	  memoffset = (GEN_INT (INTVAL (memoffset)
! 		       + tree_low_cst (DECL_FIELD_OFFSET (field), 1)
! 		       + (tree_low_cst (DECL_FIELD_BIT_OFFSET (field), 1)
! 		          / BITS_PER_UNIT)));
  	}
        /* Similarly for the decl.  */
--- 2059,2067 ----
  
  	  expr = TREE_OPERAND (expr, 0);
! 	  memoffset
! 	    = (GEN_INT (INTVAL (memoffset)
! 			+ tree_low_cst (offset, 1)
! 			+ (tree_low_cst (DECL_FIELD_BIT_OFFSET (field), 1)
! 			   / BITS_PER_UNIT)));
  	}
        /* Similarly for the decl.  */
*** explow.c	15 Jun 2004 18:02:17 -0000	1.127
--- explow.c	21 Jun 2004 22:50:01 -0000
*************** update_nonlocal_goto_save_area (void)
*** 1101,1105 ****
       of the stack save area slots.  */
    t_save = build (ARRAY_REF, ptr_type_node, cfun->nonlocal_goto_save_area,
! 		  integer_one_node);
    r_save = expand_expr (t_save, NULL_RTX, VOIDmode, EXPAND_WRITE);
  
--- 1101,1105 ----
       of the stack save area slots.  */
    t_save = build (ARRAY_REF, ptr_type_node, cfun->nonlocal_goto_save_area,
! 		  integer_one_node, NULL_TREE, NULL_TREE);
    r_save = expand_expr (t_save, NULL_RTX, VOIDmode, EXPAND_WRITE);
  
*** expr.c	19 Jun 2004 15:33:05 -0000	1.654
--- expr.c	21 Jun 2004 22:50:07 -0000
*************** get_inner_reference (tree exp, HOST_WIDE
*** 5592,5596 ****
  	{
  	  tree field = TREE_OPERAND (exp, 1);
! 	  tree this_offset = DECL_FIELD_OFFSET (field);
  
  	  /* If this field hasn't been filled in yet, don't go
--- 5592,5596 ----
  	{
  	  tree field = TREE_OPERAND (exp, 1);
! 	  tree this_offset = component_ref_field_offset (exp);
  
  	  /* If this field hasn't been filled in yet, don't go
*************** get_inner_reference (tree exp, HOST_WIDE
*** 5599,5604 ****
  	  if (this_offset == 0)
  	    break;
- 	  else
- 	    this_offset = SUBSTITUTE_PLACEHOLDER_IN_EXPR (this_offset, exp);
  
  	  offset = size_binop (PLUS_EXPR, offset, this_offset);
--- 5599,5602 ----
*************** get_inner_reference (tree exp, HOST_WIDE
*** 5613,5620 ****
  	{
  	  tree index = TREE_OPERAND (exp, 1);
! 	  tree array = TREE_OPERAND (exp, 0);
! 	  tree domain = TYPE_DOMAIN (TREE_TYPE (array));
! 	  tree low_bound = (domain ? TYPE_MIN_VALUE (domain) : 0);
! 	  tree unit_size = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (array)));
  
  	  /* We assume all arrays have sizes that are a multiple of a byte.
--- 5611,5616 ----
  	{
  	  tree index = TREE_OPERAND (exp, 1);
! 	  tree low_bound = array_ref_low_bound (exp);
! 	  tree unit_size = array_ref_element_size (exp);
  
  	  /* We assume all arrays have sizes that are a multiple of a byte.
*************** get_inner_reference (tree exp, HOST_WIDE
*** 5622,5633 ****
  	     index, then convert to sizetype and multiply by the size of the
  	     array element.  */
! 	  if (low_bound != 0 && ! integer_zerop (low_bound))
  	    index = fold (build (MINUS_EXPR, TREE_TYPE (index),
  				 index, low_bound));
  
- 	  /* If the index has a self-referential type, instantiate it with
- 	     the object; likewise for the component size.  */
- 	  index = SUBSTITUTE_PLACEHOLDER_IN_EXPR (index, exp);
- 	  unit_size = SUBSTITUTE_PLACEHOLDER_IN_EXPR (unit_size, array);
  	  offset = size_binop (PLUS_EXPR, offset,
  			       size_binop (MULT_EXPR,
--- 5618,5625 ----
  	     index, then convert to sizetype and multiply by the size of the
  	     array element.  */
! 	  if (! integer_zerop (low_bound))
  	    index = fold (build (MINUS_EXPR, TREE_TYPE (index),
  				 index, low_bound));
  
  	  offset = size_binop (PLUS_EXPR, offset,
  			       size_binop (MULT_EXPR,
*************** get_inner_reference (tree exp, HOST_WIDE
*** 5677,5680 ****
--- 5669,5736 ----
  }
  
+ /* Return a tree of sizetype representing the size, in bytes, of the element
+    of EXP, an ARRAY_REF.  */
+ 
+ tree
+ array_ref_element_size (tree exp)
+ {
+   tree aligned_size = TREE_OPERAND (exp, 3);
+   tree elmt_type = TREE_TYPE (TREE_TYPE (TREE_OPERAND (exp, 0)));
+ 
+   /* If a size was specified in the ARRAY_REF, it's the size measured
+      in alignment units of the element type.  So multiply by that value.  */
+   if (aligned_size)
+     return size_binop (MULT_EXPR, aligned_size,
+ 		       size_int (TYPE_ALIGN (elmt_type) / BITS_PER_UNIT));
+ 
+   /* Otherwise, take the size from that of the element type.  Substitute 
+      any PLACEHOLDER_EXPR that we have.  */
+   else
+     return SUBSTITUTE_PLACEHOLDER_IN_EXPR (TYPE_SIZE_UNIT (elmt_type), exp);
+ }
+ 
+ /* Return a tree representing the lower bound of the array mentioned in
+    EXP, an ARRAY_REF.  */
+ 
+ tree
+ array_ref_low_bound (tree exp)
+ {
+   tree domain_type = TYPE_DOMAIN (TREE_TYPE (TREE_OPERAND (exp, 0)));
+ 
+   /* If a lower bound is specified in EXP, use it.  */
+   if (TREE_OPERAND (exp, 2))
+     return TREE_OPERAND (exp, 2);
+ 
+   /* Otherwise, if there is a domain type and it has a lower bound, use it,
+      substituting for a PLACEHOLDER_EXPR as needed.  */
+   if (domain_type && TYPE_MIN_VALUE (domain_type))
+     return SUBSTITUTE_PLACEHOLDER_IN_EXPR (TYPE_MIN_VALUE (domain_type), exp);
+ 
+   /* Otherwise, return a zero of the appropriate type.  */
+   return fold_convert (TREE_TYPE (TREE_OPERAND (exp, 1)), integer_zero_node);
+ }
+ 
+ /* Return a tree representing the offset, in bytes, of the field referenced
+    by EXP.  This does not include any offset in DECL_FIELD_BIT_OFFSET.  */
+ 
+ tree
+ component_ref_field_offset (tree exp)
+ {
+   tree aligned_offset = TREE_OPERAND (exp, 2);
+   tree field = TREE_OPERAND (exp, 1);
+ 
+   /* If an offset was specified in the COMPONENT_REF, it's the offset measured
+      in units of DECL_OFFSET_ALIGN / BITS_PER_UNIT.  So multiply by that
+      value.  */
+   if (aligned_offset)
+     return size_binop (MULT_EXPR, aligned_offset,
+ 		       size_int (DECL_OFFSET_ALIGN (field) / BITS_PER_UNIT));
+ 
+   /* Otherwise, take the offset from that of the field.  Substitute 
+      any PLACEHOLDER_EXPR that we have.  */
+   else
+     return SUBSTITUTE_PLACEHOLDER_IN_EXPR (DECL_FIELD_OFFSET (field), exp);
+ }
+ 
  /* Return 1 if T is an expression that get_inner_reference handles.  */
  
*************** expand_expr_real_1 (tree exp, rtx target
*** 7002,7007 ****
        {
  	tree array = TREE_OPERAND (exp, 0);
! 	tree domain = TYPE_DOMAIN (TREE_TYPE (array));
! 	tree low_bound = domain ? TYPE_MIN_VALUE (domain) : integer_zero_node;
  	tree index = convert (sizetype, TREE_OPERAND (exp, 1));
  	HOST_WIDE_INT i;
--- 7058,7062 ----
        {
  	tree array = TREE_OPERAND (exp, 0);
! 	tree low_bound = array_ref_low_bound (exp);
  	tree index = convert (sizetype, TREE_OPERAND (exp, 1));
  	HOST_WIDE_INT i;
*** fold-const.c	21 Jun 2004 12:59:56 -0000	1.405
--- fold-const.c	21 Jun 2004 22:50:14 -0000
*************** fold (tree expr)
*** 7902,7909 ****
  	     the constant by the width of the field.  */
  	  if (TREE_CODE (TREE_OPERAND (varop, 0)) == COMPONENT_REF
! 	      && DECL_BIT_FIELD (TREE_OPERAND (TREE_OPERAND (varop, 0), 1)))
  	    {
  	      tree fielddecl = TREE_OPERAND (TREE_OPERAND (varop, 0), 1);
! 	      int size = TREE_INT_CST_LOW (DECL_SIZE (fielddecl));
  	      tree folded_compare, shift;
  
--- 7902,7911 ----
  	     the constant by the width of the field.  */
  	  if (TREE_CODE (TREE_OPERAND (varop, 0)) == COMPONENT_REF
! 	      && DECL_BIT_FIELD (TREE_OPERAND (TREE_OPERAND (varop, 0), 1))
! 	      && host_integerp (DECL_SIZE (TREE_OPERAND
! 					   (TREE_OPERAND (varop, 0), 1)), 1))
  	    {
  	      tree fielddecl = TREE_OPERAND (TREE_OPERAND (varop, 0), 1);
! 	      HOST_WIDE_INT size = tree_low_cst (DECL_SIZE (fielddecl), 1);
  	      tree folded_compare, shift;
  
*************** fold (tree expr)
*** 7920,7923 ****
--- 7921,7925 ----
  	      shift = build_int_2 (TYPE_PRECISION (TREE_TYPE (varop)) - size,
  				   0);
+ 	      shift = fold_convert (TREE_TYPE (varop), shift);
  	      newconst = fold (build2 (LSHIFT_EXPR, TREE_TYPE (varop),
  				       newconst, shift));
*************** fold_read_from_constant_string (tree exp
*** 10107,10117 ****
  
        if (TREE_CODE (exp) == INDIRECT_REF)
! 	{
! 	  string = string_constant (exp1, &index);
! 	}
        else
  	{
! 	  tree domain = TYPE_DOMAIN (TREE_TYPE (exp1));
! 	  tree low_bound = domain ? TYPE_MIN_VALUE (domain) : integer_zero_node;
  	  index = fold_convert (sizetype, TREE_OPERAND (exp, 1));
  	  
--- 10109,10116 ----
  
        if (TREE_CODE (exp) == INDIRECT_REF)
! 	string = string_constant (exp1, &index);
        else
  	{
! 	  tree low_bound = array_ref_low_bound (exp);
  	  index = fold_convert (sizetype, TREE_OPERAND (exp, 1));
  	  
*************** fold_read_from_constant_string (tree exp
*** 10130,10133 ****
--- 10129,10133 ----
  
        if (string
+ 	  && TREE_TYPE (exp) == TREE_TYPE (TREE_TYPE (string))
  	  && TREE_CODE (string) == STRING_CST
  	  && TREE_CODE (index) == INTEGER_CST
*************** build_fold_indirect_ref (tree t)
*** 10457,10461 ****
        else if (TREE_CODE (optype) == ARRAY_TYPE
  	       && lang_hooks.types_compatible_p (type, TREE_TYPE (optype)))
! 	return build2 (ARRAY_REF, type, op, size_zero_node);
      }
  
--- 10457,10461 ----
        else if (TREE_CODE (optype) == ARRAY_TYPE
  	       && lang_hooks.types_compatible_p (type, TREE_TYPE (optype)))
! 	return build4 (ARRAY_REF, type, op, size_zero_node, NULL_TREE, NULL_TREE);
      }
  
*************** build_fold_indirect_ref (tree t)
*** 10466,10470 ****
      {
        sub = build_fold_indirect_ref (sub);
!       return build2 (ARRAY_REF, type, sub, size_zero_node);
      }
  
--- 10466,10470 ----
      {
        sub = build_fold_indirect_ref (sub);
!       return build4 (ARRAY_REF, type, sub, size_zero_node, NULL_TREE, NULL_TREE);
      }
  
*** function.c	19 Jun 2004 19:24:56 -0000	1.527
--- function.c	21 Jun 2004 22:50:19 -0000
*************** expand_function_start (tree subr, int pa
*** 6545,6549 ****
  
        t_save = build (ARRAY_REF, ptr_type_node, cfun->nonlocal_goto_save_area,
! 		      integer_zero_node);
        r_save = expand_expr (t_save, NULL_RTX, VOIDmode, EXPAND_WRITE);
  
--- 6545,6549 ----
  
        t_save = build (ARRAY_REF, ptr_type_node, cfun->nonlocal_goto_save_area,
! 		      integer_zero_node, NULL_TREE, NULL_TREE);
        r_save = expand_expr (t_save, NULL_RTX, VOIDmode, EXPAND_WRITE);
  
*** gimple-low.c	19 Jun 2004 05:39:14 -0000	2.5
--- gimple-low.c	21 Jun 2004 22:50:20 -0000
*************** expand_var_p (tree var)
*** 477,482 ****
      return true;
  
-   ann = var_ann (var);
- 
    /* Remove all unused, unaliased temporaries.  Also remove unused, unaliased
       local variables during highly optimizing compilations.  */
--- 477,480 ----
*** gimplify.c	21 Jun 2004 09:15:20 -0000	2.20
--- gimplify.c	21 Jun 2004 22:50:25 -0000
*************** Software Foundation, 59 Temple Place - S
*** 37,40 ****
--- 36,40 ----
  #include "langhooks-def.h"
  #include "tree-flow.h"
+ #include "cgraph.h"
  #include "timevar.h"
  #include "except.h"
*************** typedef struct gimple_temp_hash_elt
*** 72,75 ****
--- 72,142 ----
  } elt_t;
  
+ /* Forward declarations.  */
+ static hashval_t gimple_tree_hash (const void *);
+ static int gimple_tree_eq (const void *, const void *);
+ static bool gimple_conditional_context (void);
+ static void gimple_push_condition (void);
+ static void gimple_pop_condition (tree *);
+ static void append_to_statement_list_1 (tree, tree *, bool);
+ static inline void remove_suffix (char *, int);
+ static inline tree create_tmp_from_val (tree);
+ static tree lookup_tmp_var (tree, bool);
+ static tree internal_get_tmp_var (tree, tree *, tree *, bool);
+ static bool should_carry_locus_p (tree);
+ static tree mostly_copy_tree_r (tree *, int *, void *);
+ static tree mark_decls_volatile_r (tree *, int *, void *);
+ static tree copy_if_shared_r (tree *, int *, void *);
+ static tree unmark_visited_r (tree *, int *, void *);
+ static void unshare_body (tree *, tree);
+ static void unvisit_body (tree *, tree);
+ static void build_stack_save_restore (tree *, tree *);
+ static enum gimplify_status gimplify_bind_expr (tree *, tree, tree *);
+ static enum gimplify_status gimplify_return_expr (tree, tree *);
+ static enum gimplify_status gimplify_loop_expr (tree *, tree *);
+ static int compare_case_labels (const void *, const void *);
+ static enum gimplify_status gimplify_switch_expr (tree *, tree *);
+ static enum gimplify_status gimplify_case_label_expr (tree *);
+ static enum gimplify_status gimplify_labeled_block_expr (tree *);
+ static enum gimplify_status gimplify_exit_block_expr (tree *);
+ static enum gimplify_status gimplify_exit_expr (tree *);
+ static enum gimplify_status gimplify_init_constructor (tree *, tree *, tree *,
+ 						       bool);
+ static void canonicalize_component_ref (tree *);
+ static void canonicalize_addr_expr (tree *);
+ static enum gimplify_status gimplify_conversion (tree *);
+ static enum gimplify_status gimplify_minimax_expr (tree *, tree *, tree *);
+ static enum gimplify_status gimplify_array_ref_to_plus (tree *, tree *,
+ 							tree *);
+ static tree build_addr_expr_with_type (tree, tree);
+ static tree build_addr_expr (tree);
+ static enum gimplify_status gimplify_compound_lval (tree *, tree *, tree *,
+ 						    bool);
+ static enum gimplify_status gimplify_self_mod_expr (tree *, tree *, tree *,
+ 						    bool);
+ static enum gimplify_status gimplify_call_expr (tree *, tree *,
+ 						bool (*) (tree));
+ static tree shortcut_cond_r (tree, tree *, tree *);
+ static tree shortcut_cond_expr (tree);
+ static tree gimple_boolify (tree);
+ static enum gimplify_status gimplify_cond_expr (tree *, tree *, tree);
+ static enum gimplify_status gimplify_modify_expr (tree *, tree *, tree *,
+ 						  bool);
+ static enum gimplify_status gimplify_modify_expr_rhs (tree *, tree *, tree *,
+ 						      tree *, tree *, bool);
+ static enum gimplify_status gimplify_variable_sized_compare (tree *);
+ static enum gimplify_status gimplify_boolean_expr (tree *);
+ static enum gimplify_status gimplify_compound_expr (tree *, tree *, bool);
+ static enum gimplify_status gimplify_statement_list (tree *);
+ static enum gimplify_status gimplify_save_expr (tree *, tree *, tree *);
+ static enum gimplify_status gimplify_addr_expr (tree *, tree *, tree *);
+ static enum gimplify_status gimplify_asm_expr (tree *, tree *, tree *);
+ static enum gimplify_status gimplify_cleanup_point_expr (tree *, tree *);
+ static void gimple_push_cleanup (tree, tree, tree *);
+ static enum gimplify_status gimplify_target_expr (tree *, tree *, tree *);
+ #ifdef ENABLE_CHECKING
+ static bool cpt_same_type (tree, tree);
+ static tree check_pointer_types_r (tree *, int *, void *);
+ #endif
+ 
  /* Return a hash value for a formal temporary table entry.  */
  
*************** create_tmp_var (tree type, const char *p
*** 356,368 ****
  
  #if defined ENABLE_CHECKING
!   /* If the type is an array or a type which must be created by the
!      frontend, something is wrong.  */
!   if (TREE_CODE (type) == ARRAY_TYPE || TREE_ADDRESSABLE (type))
!     abort ();
!   if (!COMPLETE_TYPE_P (type))
!     abort ();
!   /* Variable sized types require lots of machinery to create; the
!      optimizers shouldn't be doing anything of the sort.  */
!   if (TREE_CODE (TYPE_SIZE_UNIT (type)) != INTEGER_CST)
      abort ();
  #endif
--- 423,431 ----
  
  #if defined ENABLE_CHECKING
!   /* We don't allow types that are addressable (meaning we can't make copies),
!      incomplete, or of variable size.  */
!   if (TREE_ADDRESSABLE (type)
!       || !COMPLETE_TYPE_P (type)
!       || TREE_CODE (TYPE_SIZE_UNIT (type)) != INTEGER_CST)
      abort ();
  #endif
*************** copy_if_shared_r (tree *tp, int *walk_su
*** 654,662 ****
    enum tree_code code = TREE_CODE (t);
  
!   /* Skip types, decls, and constants.  */
    if (TREE_CODE_CLASS (code) == 't'
        || TREE_CODE_CLASS (code) == 'd'
        || TREE_CODE_CLASS (code) == 'c')
!     *walk_subtrees = 0;
  
    /* Special-case BIND_EXPR.  We should never be copying these, therefore
--- 717,733 ----
    enum tree_code code = TREE_CODE (t);
  
!   /* Skip types, decls, and constants.  But we do want to look at their
!      types and the bounds of types.  Mark them as visited so we properly
!      unmark their subtrees on the unmark pass.  If we've already seen them,
!      don't look down further.  */
    if (TREE_CODE_CLASS (code) == 't'
        || TREE_CODE_CLASS (code) == 'd'
        || TREE_CODE_CLASS (code) == 'c')
!     {
!       if (TREE_VISITED (t))
! 	*walk_subtrees = 0;
!       else
! 	TREE_VISITED (t) = 1;
!     }
  
    /* Special-case BIND_EXPR.  We should never be copying these, therefore
*************** unmark_visited_r (tree *tp, int *walk_su
*** 716,719 ****
--- 787,815 ----
  }
  
+ /* Unshare all the trees in BODY_P, a pointer to the body of FNDECL, and the
+    bodies of any nested functions.  */
+ 
+ static void
+ unshare_body (tree *body_p, tree fndecl)
+ {
+   struct cgraph_node *cgn = cgraph_node (fndecl);
+ 
+   walk_tree (body_p, copy_if_shared_r, NULL, NULL);
+   for (cgn = cgn->nested; cgn; cgn = cgn->next_nested)
+     unshare_body (&DECL_SAVED_TREE (cgn->decl), cgn->decl);
+ }
+ 
+ /* Likewise, but mark all trees as not visited.  */
+ 
+ static void
+ unvisit_body (tree *body_p, tree fndecl)
+ {
+   struct cgraph_node *cgn = cgraph_node (fndecl);
+ 
+   walk_tree (body_p, unmark_visited_r, NULL, NULL);
+   for (cgn = cgn->nested; cgn; cgn = cgn->next_nested)
+     unvisit_body (&DECL_SAVED_TREE (cgn->decl), cgn->decl);
+ }
+ 
  /* Unshare T and all the trees reached from T via TREE_CHAIN.  */
  
*************** build_and_jump (tree *label_p)
*** 1193,1197 ****
    if (label_p == NULL)
      /* If there's nowhere to jump, just fall through.  */
!     return build_empty_stmt ();
  
    if (*label_p == NULL_TREE)
--- 1289,1293 ----
    if (label_p == NULL)
      /* If there's nowhere to jump, just fall through.  */
!     return alloc_stmt_list ();
  
    if (*label_p == NULL_TREE)
*************** gimplify_exit_expr (tree *expr_p)
*** 1215,1219 ****
  
    expr = build_and_jump (&gimplify_ctxp->exit_label);
!   expr = build (COND_EXPR, void_type_node, cond, expr, build_empty_stmt ());
    *expr_p = expr;
  
--- 1311,1315 ----
  
    expr = build_and_jump (&gimplify_ctxp->exit_label);
!   expr = build (COND_EXPR, void_type_node, cond, expr, alloc_stmt_list ());
    *expr_p = expr;
  
*************** force_labels_r (tree *tp, int *walk_subt
*** 1244,1248 ****
  static enum gimplify_status
  gimplify_init_constructor (tree *expr_p, tree *pre_p,
! 			   tree *post_p, int want_value)
  {
    tree object = TREE_OPERAND (*expr_p, 0);
--- 1340,1344 ----
  static enum gimplify_status
  gimplify_init_constructor (tree *expr_p, tree *pre_p,
! 			   tree *post_p, bool want_value)
  {
    tree object = TREE_OPERAND (*expr_p, 0);
*************** gimplify_init_constructor (tree *expr_p,
*** 1280,1284 ****
  	      }
  	    else
! 	      return GS_ALL_DONE;
  	  }
  
--- 1376,1380 ----
  	      }
  	    else
! 	      return GS_UNHANDLED;
  	  }
  
*************** gimplify_init_constructor (tree *expr_p,
*** 1308,1312 ****
  	    lhd_set_decl_assembler_name (object);
  
! 	    *expr_p = build_empty_stmt ();
  	    break;
  	  }
--- 1404,1408 ----
  	    lhd_set_decl_assembler_name (object);
  
! 	    *expr_p = alloc_stmt_list ();
  	    break;
  	  }
*************** gimplify_init_constructor (tree *expr_p,
*** 1417,1427 ****
  		  abort ();
  
! 		cref = build (ARRAY_REF, t, object, purpose);
  	      }
  	    else
! 	      {
! 		cref = build (COMPONENT_REF, TREE_TYPE (purpose),
! 			      object, purpose);
! 	      }
  
  	    init = build (MODIFY_EXPR, TREE_TYPE (purpose), cref, value);
--- 1513,1521 ----
  		  abort ();
  
! 		cref = build (ARRAY_REF, t, object, purpose, NULL_TREE, NULL_TREE);
  	      }
  	    else
! 	      cref = build (COMPONENT_REF, TREE_TYPE (purpose), object,
! 			    purpose, NULL_TREE);
  
  	    init = build (MODIFY_EXPR, TREE_TYPE (purpose), cref, value);
*************** gimplify_init_constructor (tree *expr_p,
*** 1431,1435 ****
  	  }
  
! 	*expr_p = build_empty_stmt ();
        }
        break;
--- 1525,1529 ----
  	  }
  
! 	*expr_p = alloc_stmt_list ();
        }
        break;
*************** canonicalize_component_ref (tree *expr_p
*** 1553,1568 ****
  
  /* If a NOP conversion is changing a pointer to array of foo to a pointer
!    to foo, embed that change in the ADDR_EXPR.  Lest we perturb the type
!    system too badly, we must take extra steps to ensure that the ADDR_EXPR
!    and the addressed object continue to agree on types.  */
! /* ??? We might could do better if we recognize
! 	T array[N][M];
! 	(T *)&array
     ==>
! 	&array[0][0];
! */
  
  static void
! canonicalize_addr_expr (tree* expr_p)
  {
    tree expr = *expr_p;
--- 1647,1661 ----
  
  /* If a NOP conversion is changing a pointer to array of foo to a pointer
!    to foo, embed that change in the ADDR_EXPR by converting 
!       T array[U];
!       (T *)&array
     ==>
!       &array[L]
!    where L is the lower bound.  Only do this for constant lower bound since
!    we have no place to put any statements made during gimplification of
!    the lower bound.  */
  
  static void
! canonicalize_addr_expr (tree *expr_p)
  {
    tree expr = *expr_p;
*************** canonicalize_addr_expr (tree* expr_p)
*** 1593,1598 ****
      return;
  
    /* All checks succeeded.  Build a new node to merge the cast.  */
!   *expr_p = build1 (ADDR_EXPR, ctype, obj_expr);
  }
  
--- 1686,1703 ----
      return;
  
+   /* The lower bound and element sizes must be constant.  */
+   if (TREE_CODE (TYPE_SIZE_UNIT (dctype)) != INTEGER_CST
+       || !TYPE_DOMAIN (datype) || !TYPE_MIN_VALUE (TYPE_DOMAIN (datype))
+       || TREE_CODE (TYPE_MIN_VALUE (TYPE_DOMAIN (datype))) != INTEGER_CST)
+     return;
+ 
    /* All checks succeeded.  Build a new node to merge the cast.  */
!   *expr_p = build4 (ARRAY_REF, dctype, obj_expr,
! 		    TYPE_MIN_VALUE (TYPE_DOMAIN (datype)),
! 		    TYPE_MIN_VALUE (TYPE_DOMAIN (datype)),
! 		    size_binop (EXACT_DIV_EXPR, TYPE_SIZE_UNIT (dctype),
! 				size_int (TYPE_ALIGN (dctype)
! 					  / BITS_PER_UNIT)));
!   *expr_p = build1 (ADDR_EXPR, ctype, *expr_p);
  }
  
*************** gimplify_minimax_expr (tree *expr_p, tre
*** 1667,1671 ****
  }
  
! /* Subroutine of gimplify_compound_lval and gimplify_array_ref.
     Converts an ARRAY_REF to the equivalent *(&array + offset) form.  */
  
--- 1772,1776 ----
  }
  
! /* Subroutine of gimplify_compound_lval.
     Converts an ARRAY_REF to the equivalent *(&array + offset) form.  */
  
*************** gimplify_array_ref_to_plus (tree *expr_p
*** 1676,1698 ****
    tree arrtype = TREE_TYPE (array);
    tree elttype = TREE_TYPE (arrtype);
!   tree size = size_in_bytes (elttype);
    tree ptrtype = build_pointer_type (elttype);
    enum tree_code add_code = PLUS_EXPR;
    tree idx = TREE_OPERAND (*expr_p, 1);
!   tree minidx, offset, addr, result;
    enum gimplify_status ret;
  
    /* If the array domain does not start at zero, apply the offset.  */
!   minidx = TYPE_DOMAIN (arrtype);
!   if (minidx)
      {
!       minidx = TYPE_MIN_VALUE (minidx);
!       if (minidx && !integer_zerop (minidx))
! 	{
! 	  idx = convert (TREE_TYPE (minidx), idx);
! 	  idx = fold (build (MINUS_EXPR, TREE_TYPE (minidx), idx, minidx));
! 	}
      }
! 
    /* If the index is negative -- a technically invalid situation now
       that we've biased the index back to zero -- then casting it to
--- 1781,1799 ----
    tree arrtype = TREE_TYPE (array);
    tree elttype = TREE_TYPE (arrtype);
!   tree size = array_ref_element_size (*expr_p);
    tree ptrtype = build_pointer_type (elttype);
    enum tree_code add_code = PLUS_EXPR;
    tree idx = TREE_OPERAND (*expr_p, 1);
!   tree minidx = unshare_expr (array_ref_low_bound (*expr_p));
!   tree offset, addr, result;
    enum gimplify_status ret;
  
    /* If the array domain does not start at zero, apply the offset.  */
!   if (!integer_zerop (minidx))
      {
!       idx = convert (TREE_TYPE (minidx), idx);
!       idx = fold (build (MINUS_EXPR, TREE_TYPE (minidx), idx, minidx));
      }
!   
    /* If the index is negative -- a technically invalid situation now
       that we've biased the index back to zero -- then casting it to
*************** gimplify_array_ref_to_plus (tree *expr_p
*** 1708,1712 ****
  
    /* Pointer arithmetic must be done in sizetype.  */
!   idx = convert (sizetype, idx);
  
    /* Convert the index to a byte offset.  */
--- 1809,1813 ----
  
    /* Pointer arithmetic must be done in sizetype.  */
!   idx = fold_convert (sizetype, idx);
  
    /* Convert the index to a byte offset.  */
*************** gimplify_array_ref_to_plus (tree *expr_p
*** 1724,1727 ****
--- 1825,1866 ----
  }
  
+ /*  Build an expression for the address of T.  Folds away INDIRECT_REF to
+     avoid confusing the gimplify process.  */
+ 
+ static tree
+ build_addr_expr_with_type (tree t, tree ptrtype)
+ {
+   if (TREE_CODE (t) == INDIRECT_REF)
+     {
+       t = TREE_OPERAND (t, 0);
+       if (TREE_TYPE (t) != ptrtype)
+ 	t = build1 (NOP_EXPR, ptrtype, t);
+     }
+   else
+     {
+       tree base = t;
+ 
+       if (TREE_CODE (base) == REALPART_EXPR
+ 	  || TREE_CODE (base) == IMAGPART_EXPR)
+ 	base = TREE_OPERAND (base, 0);
+       else
+ 	while (handled_component_p (base))
+ 	  base = TREE_OPERAND (base, 0);
+ 
+       if (DECL_P (base))
+ 	TREE_ADDRESSABLE (base) = 1;
+ 
+       t = build1 (ADDR_EXPR, ptrtype, t);
+     }
+ 
+   return t;
+ }
+ 
+ static tree
+ build_addr_expr (tree t)
+ {
+   return build_addr_expr_with_type (t, build_pointer_type (TREE_TYPE (t)));
+ }
+ 
  /* Gimplify the COMPONENT_REF, ARRAY_REF, REALPART_EXPR or IMAGPART_EXPR
     node pointed by EXPR_P.
*************** gimplify_array_ref_to_plus (tree *expr_p
*** 1748,1761 ****
  static enum gimplify_status
  gimplify_compound_lval (tree *expr_p, tree *pre_p,
! 			tree *post_p, int want_lvalue)
  {
    tree *p;
-   enum tree_code code;
    varray_type stack;
!   enum gimplify_status ret;
  
  #if defined ENABLE_CHECKING
    if (TREE_CODE (*expr_p) != ARRAY_REF
        && TREE_CODE (*expr_p) != COMPONENT_REF
        && TREE_CODE (*expr_p) != REALPART_EXPR
        && TREE_CODE (*expr_p) != IMAGPART_EXPR)
--- 1887,1901 ----
  static enum gimplify_status
  gimplify_compound_lval (tree *expr_p, tree *pre_p,
! 			tree *post_p, bool want_lvalue)
  {
    tree *p;
    varray_type stack;
!   enum gimplify_status ret = GS_OK, tret;
  
  #if defined ENABLE_CHECKING
    if (TREE_CODE (*expr_p) != ARRAY_REF
+       && TREE_CODE (*expr_p) != ARRAY_RANGE_REF
        && TREE_CODE (*expr_p) != COMPONENT_REF
+       && TREE_CODE (*expr_p) != BIT_FIELD_REF
        && TREE_CODE (*expr_p) != REALPART_EXPR
        && TREE_CODE (*expr_p) != IMAGPART_EXPR)
*************** gimplify_compound_lval (tree *expr_p, tr
*** 1763,1808 ****
  #endif
  
-   code = ERROR_MARK;	/* [GIMPLE] Avoid uninitialized use warning.  */
- 
    /* Create a stack of the subexpressions so later we can walk them in
       order from inner to outer.  */
    VARRAY_TREE_INIT (stack, 10, "stack");
  
!   for (p = expr_p;
!        TREE_CODE (*p) == ARRAY_REF
!        || TREE_CODE (*p) == COMPONENT_REF
!        || TREE_CODE (*p) == REALPART_EXPR
!        || TREE_CODE (*p) == IMAGPART_EXPR;
!        p = &TREE_OPERAND (*p, 0))
!     {
!       code = TREE_CODE (*p);
!       if (code == ARRAY_REF)
! 	{
! 	  tree elttype = TREE_TYPE (TREE_TYPE (TREE_OPERAND (*p, 0)));
! 	  if (!TREE_CONSTANT (TYPE_SIZE_UNIT (elttype)))
! 	    /* If the size of the array elements is not constant,
! 	       computing the offset is non-trivial, so expose it.  */
! 	    break;
! 	}
        VARRAY_PUSH_TREE (stack, *p);
-     }
  
!   /* Now 'p' points to the first bit that isn't a ref, 'code' is the
!      TREE_CODE of the last bit that was, and 'stack' is a stack of pointers
!      to all the refs we've walked through.
! 
!      Gimplify the base, and then process each of the outer nodes from left
!      to right.  */
!   ret = gimplify_expr (p, pre_p, post_p, is_gimple_min_lval,
! 		       code != ARRAY_REF ? fb_either : fb_lvalue);
  
    for (; VARRAY_ACTIVE_SIZE (stack) > 0; )
      {
        tree t = VARRAY_TOP_TREE (stack);
!       if (TREE_CODE (t) == ARRAY_REF)
  	{
! 	  /* Gimplify the dimension.  */
! 	  enum gimplify_status tret;
! 	  /* Temporary fix for gcc.c-torture/execute/20040313-1.c.
  	     Gimplify non-constant array indices into a temporary
  	     variable.
--- 1903,1933 ----
  #endif
  
    /* Create a stack of the subexpressions so later we can walk them in
       order from inner to outer.  */
    VARRAY_TREE_INIT (stack, 10, "stack");
  
!   /* We can either handle one REALPART_EXPR or IMAGEPART_EXPR or
!      nest of handled components.  */
!   if (TREE_CODE (*expr_p) == REALPART_EXPR
!       || TREE_CODE (*expr_p) == IMAGPART_EXPR)
!     p = &TREE_OPERAND (*expr_p, 0);
!   else
!     for (p = expr_p; handled_component_p (*p); p = &TREE_OPERAND (*p, 0))
        VARRAY_PUSH_TREE (stack, *p);
  
!   /* Now STACK is a stack of pointers to all the refs we've walked through
!      and P points to the innermost expression.
  
+      Process each of the outer nodes from left to right, then gimplify the
+      base.  We need to do it in this order so that PLACEHOLDER_EXPRs
+      can be resolved.  */
    for (; VARRAY_ACTIVE_SIZE (stack) > 0; )
      {
        tree t = VARRAY_TOP_TREE (stack);
! 
!       if (TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF)
  	{
! 	  /* Gimplify the dimension.
! 	     Temporary fix for gcc.c-torture/execute/20040313-1.c.
  	     Gimplify non-constant array indices into a temporary
  	     variable.
*************** gimplify_compound_lval (tree *expr_p, tr
*** 1816,1827 ****
  	      tret = gimplify_expr (&TREE_OPERAND (t, 1), pre_p, post_p,
  				    is_gimple_tmp_var, fb_rvalue);
! 	      if (tret == GS_ERROR)
! 		ret = GS_ERROR;
  	    }
  	}
        recalculate_side_effects (t);
        VARRAY_POP (stack);
      }
  
    /* If the outermost expression is a COMPONENT_REF, canonicalize its type.  */
    if (!want_lvalue && TREE_CODE (*expr_p) == COMPONENT_REF)
--- 1941,2020 ----
  	      tret = gimplify_expr (&TREE_OPERAND (t, 1), pre_p, post_p,
  				    is_gimple_tmp_var, fb_rvalue);
! 	      ret = MIN (ret, tret);
! 	    }
! 
! 	  /* Gimplify the low bound and element type size and put them into
! 	     the ARRAY_REF.  If these values are set, they have already been
! 	     gimplified.  */
! 	  if (!TREE_OPERAND (t, 2))
! 	    {
! 	      TREE_OPERAND (t, 2) = unshare_expr (array_ref_low_bound (t));
! 	      if (!is_gimple_min_invariant (TREE_OPERAND (t, 2)))
! 		{
! 		  tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p, post_p,
! 					is_gimple_tmp_var, fb_rvalue);
! 		  ret = MIN (ret, tret);
! 		}
! 	    }
! 
! 	  if (!TREE_OPERAND (t, 3))
! 	    {
! 	      tree elmt_type = TREE_TYPE (TREE_TYPE (TREE_OPERAND (t, 0)));
! 	      tree elmt_size = unshare_expr (array_ref_element_size (t));
! 	      tree factor = size_int (TYPE_ALIGN (elmt_type) / BITS_PER_UNIT);
! 
! 	      /* Divide the element size by the alignment of the element
! 		 type (above).  */
! 	      elmt_size = size_binop (EXACT_DIV_EXPR, elmt_size, factor);
! 
! 	      TREE_OPERAND (t, 3) = elmt_size;
! 	      if (!is_gimple_min_invariant (TREE_OPERAND (t, 3)))
! 		{
! 		  tret = gimplify_expr (&TREE_OPERAND (t, 3), pre_p, post_p,
! 					is_gimple_tmp_var, fb_rvalue);
! 		  ret = MIN (ret, tret);
! 		}
  	    }
  	}
+       else if (TREE_CODE (t) == COMPONENT_REF)
+ 	{
+ 	  /* Set the field offset into T and gimplify it.  */
+ 	  if (!TREE_OPERAND (t, 2))
+ 	    {
+ 	      tree offset = unshare_expr (component_ref_field_offset (t));
+ 	      tree field = TREE_OPERAND (t, 1);
+ 	      tree factor
+ 		= size_int (DECL_OFFSET_ALIGN (field) / BITS_PER_UNIT);
+ 
+ 	      /* Divide the offset by its alignment.  */
+ 	      offset = size_binop (EXACT_DIV_EXPR, offset, factor);
+ 
+ 	      TREE_OPERAND (t, 2) = offset;
+ 	      if (!is_gimple_min_invariant (TREE_OPERAND (t, 2)))
+ 		{
+ 		  tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p, post_p,
+ 					is_gimple_tmp_var, fb_rvalue);
+ 		  ret = MIN (ret, tret);
+ 		}
+ 	    }
+ 	}
+       else if (TREE_CODE (t) == BIT_FIELD_REF)
+ 	{
+ 	  tret = gimplify_expr (&TREE_OPERAND (t, 1), pre_p, post_p,
+ 				is_gimple_val, fb_rvalue);
+ 	  ret = MIN (ret, tret);
+ 	  tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p, post_p,
+ 				is_gimple_val, fb_rvalue);
+ 	  ret = MIN (ret, tret);
+ 	}
+ 	  
        recalculate_side_effects (t);
        VARRAY_POP (stack);
      }
  
+   tret = gimplify_expr (p, pre_p, post_p, is_gimple_min_lval,
+ 			want_lvalue ? fb_lvalue : fb_rvalue);
+   ret = MIN (ret, tret);
+ 
    /* If the outermost expression is a COMPONENT_REF, canonicalize its type.  */
    if (!want_lvalue && TREE_CODE (*expr_p) == COMPONENT_REF)
*************** gimplify_compound_lval (tree *expr_p, tr
*** 1834,1864 ****
  }
  
- /*  Re-write the ARRAY_REF node pointed by EXPR_P.
- 
-     PRE_P points to the list where side effects that must happen before
- 	*EXPR_P should be stored.
- 
-     POST_P points to the list where side effects that must happen after
- 	*EXPR_P should be stored.
- 
-     FIXME: ARRAY_REF currently doesn't accept a pointer as the array
-     argument, so this gimplification uses an INDIRECT_REF of ARRAY_TYPE.
-     ARRAY_REF should be extended.  */
- 
- static enum gimplify_status
- gimplify_array_ref (tree *expr_p, tree *pre_p,
- 		    tree *post_p, int want_lvalue)
- {
-   tree elttype = TREE_TYPE (TREE_TYPE (TREE_OPERAND (*expr_p, 0)));
-   if (!TREE_CONSTANT (TYPE_SIZE_UNIT (elttype)))
-     /* If the size of the array elements is not constant,
-        computing the offset is non-trivial, so expose it.  */
-     return gimplify_array_ref_to_plus (expr_p, pre_p, post_p);
-   else
-     /* Handle array and member refs together for now.  When alias analysis
-        improves, we may want to go back to handling them separately.  */
-     return gimplify_compound_lval (expr_p, pre_p, post_p, want_lvalue);
- }
- 
  /*  Gimplify the self modifying expression pointed by EXPR_P (++, --, +=, -=).
  
--- 2027,2030 ----
*************** gimplify_array_ref (tree *expr_p, tree *
*** 1874,1878 ****
  static enum gimplify_status
  gimplify_self_mod_expr (tree *expr_p, tree *pre_p, tree *post_p,
! 			int want_value)
  {
    enum tree_code code;
--- 2040,2044 ----
  static enum gimplify_status
  gimplify_self_mod_expr (tree *expr_p, tree *pre_p, tree *post_p,
! 			bool want_value)
  {
    enum tree_code code;
*************** shortcut_cond_expr (tree expr)
*** 2167,2171 ****
  	  pred = TREE_OPERAND (pred, 0);
  	  expr = build (COND_EXPR, void_type_node, pred, then_,
! 			build_empty_stmt ());
  	}
      }
--- 2333,2337 ----
  	  pred = TREE_OPERAND (pred, 0);
  	  expr = build (COND_EXPR, void_type_node, pred, then_,
! 			alloc_stmt_list ());
  	}
      }
*************** shortcut_cond_expr (tree expr)
*** 2182,2186 ****
  	  pred = TREE_OPERAND (pred, 0);
  	  expr = build (COND_EXPR, void_type_node, pred,
! 			build_empty_stmt (), else_);
  	}
      }
--- 2348,2352 ----
  	  pred = TREE_OPERAND (pred, 0);
  	  expr = build (COND_EXPR, void_type_node, pred,
! 			alloc_stmt_list (), else_);
  	}
      }
*************** shortcut_cond_expr (tree expr)
*** 2208,2212 ****
      {
        true_label = GOTO_DESTINATION (then_);
!       then_ = build_empty_stmt ();
      }
  
--- 2374,2378 ----
      {
        true_label = GOTO_DESTINATION (then_);
!       then_ = alloc_stmt_list ();
      }
  
*************** shortcut_cond_expr (tree expr)
*** 2215,2219 ****
      {
        false_label = GOTO_DESTINATION (else_);
!       else_ = build_empty_stmt ();
      }
  
--- 2381,2385 ----
      {
        false_label = GOTO_DESTINATION (else_);
!       else_ = alloc_stmt_list ();
      }
  
*************** gimple_boolify (tree expr)
*** 2330,2333 ****
--- 2496,2501 ----
      The second form is used when *EXPR_P is of type void.
  
+     TARGET is the tree for T1 above.
+ 
      PRE_P points to the list where side effects that must happen before
  	*EXPR_P should be stored.  */
*************** gimplify_modify_expr (tree *expr_p, tree
*** 2457,2461 ****
    tree *from_p = &TREE_OPERAND (*expr_p, 1);
    tree *to_p = &TREE_OPERAND (*expr_p, 0);
!   enum gimplify_status ret;
  
  #if defined ENABLE_CHECKING
--- 2625,2629 ----
    tree *from_p = &TREE_OPERAND (*expr_p, 1);
    tree *to_p = &TREE_OPERAND (*expr_p, 0);
!   enum gimplify_status ret = GS_UNHANDLED;
  
  #if defined ENABLE_CHECKING
*************** gimplify_modify_expr (tree *expr_p, tree
*** 2468,2505 ****
      TREE_SET_CODE (*expr_p, MODIFY_EXPR);
  
!   ret = gimplify_expr (to_p, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
!   if (ret == GS_ERROR)
      return ret;
  
!   /* If we are initializing something from a TARGET_EXPR, strip the
!      TARGET_EXPR and initialize it directly, if possible.  This can't
!      be done if the initializer is void, since that implies that the
!      temporary is set in some non-trivial way.  */
!   /* What about code that pulls out the temp and uses it elsewhere?  I
!      think that such code never uses the TARGET_EXPR as an initializer.  If
!      I'm wrong, we'll abort because the temp won't have any RTL.  In that
!      case, I guess we'll need to replace references somehow.  */
!   if (TREE_CODE (*from_p) == TARGET_EXPR)
!     {
!       tree init = TARGET_EXPR_INITIAL (*from_p);
!       if (!VOID_TYPE_P (TREE_TYPE (init)))
!         *from_p = init;
!     }
! 
!   /* If we're assigning from a ?: expression with ADDRESSABLE type, push
!      the assignment down into the branches, since we can't generate a
!      temporary of such a type.  */
!   if (TREE_CODE (*from_p) == COND_EXPR
!       && TREE_ADDRESSABLE (TREE_TYPE (*from_p)))
!     {
!       *expr_p = *from_p;
!       return gimplify_cond_expr (expr_p, pre_p, *to_p);
      }
  
    ret = gimplify_expr (from_p, pre_p, post_p, is_gimple_rhs, fb_rvalue);
    if (ret == GS_ERROR)
      return ret;
  
!   ret = gimplify_init_constructor (expr_p, pre_p, post_p, want_value);
    if (ret != GS_UNHANDLED)
      return ret;
--- 2636,2684 ----
      TREE_SET_CODE (*expr_p, MODIFY_EXPR);
  
!   /* See if any simplifications can be done based on what the RHS is.  */
!   ret = gimplify_modify_expr_rhs (expr_p, from_p, to_p, pre_p, post_p,
! 				  want_value);
!   if (ret != GS_UNHANDLED)
      return ret;
  
!   /* If the value being copied is of variable width, expose the length
!      if the copy by converting the whole thing to a memcpy.  Note that
!      we need to do this before gimplifying any of the operands
!      so that we can resolve any PLACEHOLDER_EXPRs in the size.  */
!   if (TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (*to_p))) != INTEGER_CST)
!     {
!       tree args, t, dest;
! 
!       t = TYPE_SIZE_UNIT (TREE_TYPE (*to_p));
!       t = SUBSTITUTE_PLACEHOLDER_IN_EXPR (t, *to_p);
!       t = SUBSTITUTE_PLACEHOLDER_IN_EXPR (t, *from_p);
!       t = unshare_expr (t);
!       args = tree_cons (NULL, t, NULL);
!       t = build_fold_addr_expr (*from_p);
!       args = tree_cons (NULL, t, args);
!       dest = build_fold_addr_expr (*to_p);
!       args = tree_cons (NULL, dest, args);
!       t = implicit_built_in_decls[BUILT_IN_MEMCPY];
!       t = build_function_call_expr (t, args);
!       if (want_value)
! 	{
! 	  t = build1 (NOP_EXPR, TREE_TYPE (dest), t);
! 	  t = build1 (INDIRECT_REF, TREE_TYPE (*to_p), t);
! 	}
!       *expr_p = t;
!       return GS_OK;
      }
  
+   ret = gimplify_expr (to_p, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
+   if (ret == GS_ERROR)
+     return ret;
+ 
    ret = gimplify_expr (from_p, pre_p, post_p, is_gimple_rhs, fb_rvalue);
    if (ret == GS_ERROR)
      return ret;
  
!   /* Now see if the above changed *from_p to something we handle specially.  */
!   ret = gimplify_modify_expr_rhs (expr_p, from_p, to_p, pre_p, post_p,
! 				  want_value);
    if (ret != GS_UNHANDLED)
      return ret;
*************** gimplify_modify_expr (tree *expr_p, tree
*** 2531,2563 ****
  	gimplify_expr (from_p, pre_p, post_p, is_gimple_val, fb_rvalue);
  
-       /* If the value being copied is of variable width, expose the length
- 	 if the copy by converting the whole thing to a memcpy.  */
-       /* ??? Except that we can't manage this with VA_ARG_EXPR.  Yes, this
- 	 does leave us with an edge condition that doesn't work.  The only
- 	 way out is to rearrange how VA_ARG_EXPR works.  */
-       if (TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (*to_p))) != INTEGER_CST
- 	  && TREE_CODE (*from_p) != VA_ARG_EXPR)
- 	{
- 	  tree args, t, dest;
- 
- 	  t = TYPE_SIZE_UNIT (TREE_TYPE (*to_p));
- 	  t = unshare_expr (t);
- 	  args = tree_cons (NULL, t, NULL);
- 	  t = build_fold_addr_expr (*from_p);
- 	  args = tree_cons (NULL, t, args);
- 	  dest = build_fold_addr_expr (*to_p);
- 	  args = tree_cons (NULL, dest, args);
- 	  t = implicit_built_in_decls[BUILT_IN_MEMCPY];
- 	  t = build_function_call_expr (t, args);
- 	  if (want_value)
- 	    {
- 	      t = build1 (NOP_EXPR, TREE_TYPE (dest), t);
- 	      t = build1 (INDIRECT_REF, TREE_TYPE (*to_p), t);
- 	    }
- 	  *expr_p = t;
- 
- 	  return GS_OK;
- 	}
- 
        ret = want_value ? GS_OK : GS_ALL_DONE;
      }
--- 2710,2713 ----
*************** gimplify_modify_expr (tree *expr_p, tree
*** 2572,2575 ****
--- 2722,2820 ----
  }
  
+ /*  Subroutine of above to do simplications of MODIFY_EXPRs based on
+     the code of the RHS.  We loop for as long as we can do something.  */
+ 
+ static enum gimplify_status
+ gimplify_modify_expr_rhs (tree *expr_p, tree *from_p, tree *to_p, tree *pre_p,
+ 			  tree *post_p, bool want_value)
+ {
+   enum gimplify_status ret = GS_OK;
+ 
+   while (ret != GS_UNHANDLED)
+     switch (TREE_CODE (*from_p))
+       {
+       case TARGET_EXPR:
+ 	{
+ 	  /* If we are initializing something from a TARGET_EXPR, strip the
+ 	     TARGET_EXPR and initialize it directly, if possible.  This can't
+ 	     be done if the initializer is void, since that implies that the
+ 	     temporary is set in some non-trivial way.
+ 
+ 	     ??? What about code that pulls out the temp and uses it
+ 	     elsewhere? I think that such code never uses the TARGET_EXPR as
+ 	     an initializer.  If I'm wrong, we'll abort because the temp won't
+ 	     have any RTL.  In that case, I guess we'll need to replace
+ 	     references somehow.  */
+ 	  tree init = TARGET_EXPR_INITIAL (*from_p);
+ 
+ 	  if (!VOID_TYPE_P (TREE_TYPE (init)))
+ 	    {
+ 	      *from_p = init;
+ 	      ret = GS_OK;
+ 	    }
+ 	  else
+ 	    ret = GS_UNHANDLED;
+ 	}
+ 	break;
+ 
+       case COMPOUND_EXPR:
+ 	/* Remove any COMPOUND_EXPR in the RHS so the following cases will be
+ 	   caught.  */
+ 	gimplify_compound_expr (from_p, pre_p, true);
+ 	ret = GS_OK;
+ 	break;
+ 
+       case CONSTRUCTOR:
+ 	/* If we're initializing from a CONSTRUCTOR, break this into
+ 	   individual MODIFY_EXPRs.  */
+ 	return gimplify_init_constructor (expr_p, pre_p, post_p, want_value);
+ 
+       case COND_EXPR:
+ 	/* If we're assigning from a ?: expression with ADDRESSABLE type, push
+ 	   the assignment down into the branches, since we can't generate a
+ 	   temporary of such a type.  */
+ 	if (TREE_ADDRESSABLE (TREE_TYPE (*from_p)))
+ 	  {
+ 	    *expr_p = *from_p;
+ 	    return gimplify_cond_expr (expr_p, pre_p, *to_p);
+ 	  }
+ 	else
+ 	  ret = GS_UNHANDLED;
+ 	break;
+ 
+       default:
+ 	ret = GS_UNHANDLED;
+ 	break;
+       }
+ 
+   return ret;
+ }
+ 
+ /*  Gimplify a comparison between two variable-sized objects.  Do this
+     with a call to BUILT_IN_MEMCMP.  */
+ 
+ static enum gimplify_status
+ gimplify_variable_sized_compare (tree *expr_p)
+ {
+   tree op0 = TREE_OPERAND (*expr_p, 0);
+   tree op1 = TREE_OPERAND (*expr_p, 1);
+   tree args, t, dest;
+ 
+   t = TYPE_SIZE_UNIT (TREE_TYPE (op0));
+   t = SUBSTITUTE_PLACEHOLDER_IN_EXPR (t, op0);
+   t = unshare_expr (t);
+   args = tree_cons (NULL, t, NULL);
+   t = build_addr_expr (op1);
+   args = tree_cons (NULL, t, args);
+   dest = build_addr_expr (op0);
+   args = tree_cons (NULL, dest, args);
+   t = implicit_built_in_decls[BUILT_IN_MEMCMP];
+   t = build_function_call_expr (t, args);
+   *expr_p
+     = build (TREE_CODE (*expr_p), TREE_TYPE (*expr_p), t, integer_zero_node);
+ 
+   return GS_OK;
+ }
+ 
  /*  Gimplify TRUTH_ANDIF_EXPR and TRUTH_ORIF_EXPR expressions.  EXPR_P
      points to the expression to gimplify.
*************** gimplify_save_expr (tree *expr_p, tree *
*** 2697,2701 ****
        ret = gimplify_expr (& body, pre_p, post_p, is_gimple_stmt, fb_none);
        append_to_statement_list (body, pre_p);
!       *expr_p = build_empty_stmt ();
      }
    else
--- 2942,2946 ----
        ret = gimplify_expr (& body, pre_p, post_p, is_gimple_stmt, fb_none);
        append_to_statement_list (body, pre_p);
!       *expr_p = alloc_stmt_list ();
      }
    else
*************** gimplify_addr_expr (tree *expr_p, tree *
*** 2743,2749 ****
  
        /* This added an INDIRECT_REF.  Fold it away.  */
!       op0 = TREE_OPERAND (TREE_OPERAND (expr, 0), 0);
  
!       *expr_p = op0;
        break;
  
--- 2988,3000 ----
  
        /* This added an INDIRECT_REF.  Fold it away.  */
!       *expr_p = TREE_OPERAND (TREE_OPERAND (expr, 0), 0);
!       break;
  
!     case VIEW_CONVERT_EXPR:
!       /* Take the address of our operand and then convert it to the type of
! 	 this ADDR_EXPR.  */
!       *expr_p = fold_convert (TREE_TYPE (expr),
! 			      build_addr_expr (TREE_OPERAND (op0, 0)));
!       ret = GS_OK;
        break;
  
*************** gimple_push_cleanup (tree var, tree clea
*** 2994,2998 ****
  			  boolean_true_node);
        cleanup = build (COND_EXPR, void_type_node, flag, cleanup,
! 		       build_empty_stmt ());
        wce = build (WITH_CLEANUP_EXPR, void_type_node, NULL_TREE,
  		   cleanup, NULL_TREE);
--- 3245,3249 ----
  			  boolean_true_node);
        cleanup = build (COND_EXPR, void_type_node, flag, cleanup,
! 		       alloc_stmt_list ());
        wce = build (WITH_CLEANUP_EXPR, void_type_node, NULL_TREE,
  		   cleanup, NULL_TREE);
*************** gimplify_expr (tree *expr_p, tree *pre_p
*** 3209,3216 ****
  
  	case ARRAY_REF:
! 	  ret = gimplify_array_ref (expr_p, pre_p, post_p,
! 				    fallback & fb_lvalue);
! 	  break;
! 
  	case COMPONENT_REF:
  	  ret = gimplify_compound_lval (expr_p, pre_p, post_p,
--- 3460,3466 ----
  
  	case ARRAY_REF:
! 	case ARRAY_RANGE_REF:
! 	case REALPART_EXPR:
! 	case IMAGPART_EXPR:
  	case COMPONENT_REF:
  	  ret = gimplify_compound_lval (expr_p, pre_p, post_p,
*************** gimplify_expr (tree *expr_p, tree *pre_p
*** 3233,3242 ****
  	  break;
  
- 	case REALPART_EXPR:
- 	case IMAGPART_EXPR:
- 	  ret = gimplify_compound_lval (expr_p, pre_p, post_p,
- 					fallback & fb_lvalue);
- 	  break;
- 
  	case MODIFY_EXPR:
  	case INIT_EXPR:
--- 3483,3486 ----
*************** gimplify_expr (tree *expr_p, tree *pre_p
*** 3266,3269 ****
--- 3510,3541 ----
  	  break;
  
+ 	case VIEW_CONVERT_EXPR:
+ 	  if (VOID_TYPE_P (TREE_TYPE (*expr_p))
+ 	      || fallback == fb_none)
+ 	    {
+ 	      /* Just strip a conversion to void (or in void context) and
+ 		 try again.  */
+ 	      *expr_p = TREE_OPERAND (*expr_p, 0);
+ 	      break;
+ 	    }
+ 
+ 	  /* If both types are BLKmode or if one type is of variable size,
+ 	     convert this into a pointer punning operation.  This avoids
+ 	     copies of large data or making a variable-size temporary.  */
+ 	  if ((TYPE_MODE (TREE_TYPE (*expr_p)) == BLKmode
+ 	       && TYPE_MODE (TREE_TYPE (TREE_OPERAND (*expr_p, 0))) == BLKmode)
+ 	      || !TREE_CONSTANT (TYPE_SIZE (TREE_TYPE (*expr_p)))
+ 	      || !TREE_CONSTANT (TYPE_SIZE (TREE_TYPE
+ 					    (TREE_OPERAND (*expr_p,0)))))
+ 	    {
+ 	      tree restype = TREE_TYPE (*expr_p);
+ 	      *expr_p = build1 (INDIRECT_REF, TREE_TYPE (*expr_p),
+ 				fold_convert (build_pointer_type (restype),
+ 					      build_addr_expr
+ 					      (TREE_OPERAND (*expr_p, 0))));
+ 	      break;
+ 	    }
+ 	  goto unary;
+ 
  	case CONVERT_EXPR:
  	case NOP_EXPR:
*************** gimplify_expr (tree *expr_p, tree *pre_p
*** 3294,3297 ****
--- 3566,3570 ----
  	case FIX_FLOOR_EXPR:
  	case FIX_ROUND_EXPR:
+ 	unary:
  	  /* unary_expr: ... | '(' cast ')' val | ...  */
  	  ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
*************** gimplify_expr (tree *expr_p, tree *pre_p
*** 3485,3491 ****
  
  	default:
  	  /* If *EXPR_P does not need to be special-cased, handle it
  	     according to its class.  */
! 	  if (TREE_CODE_CLASS (TREE_CODE (*expr_p)) == '1')
  	    ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
  				 post_p, is_gimple_val, fb_rvalue);
--- 3758,3773 ----
  
  	default:
+ 	  /* If this is a comparison of objects of aggregate type, handle
+ 	     it specially (by converting to a call to memcmp).  It would be
+ 	     nice to only have to do this for variable-sized objects, but
+ 	     then we'd have to allow the same nest of reference nodes we
+ 	     allow for MODIFY_EXPR and that's too complex.  */
+ 	  if (TREE_CODE_CLASS (TREE_CODE (*expr_p)) == '<'
+ 	      && (AGGREGATE_TYPE_P (TREE_TYPE (TREE_OPERAND (*expr_p, 1)))))
+ 	    ret = gimplify_variable_sized_compare (expr_p);
+ 
  	  /* If *EXPR_P does not need to be special-cased, handle it
  	     according to its class.  */
! 	  else if (TREE_CODE_CLASS (TREE_CODE (*expr_p)) == '1')
  	    ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
  				 post_p, is_gimple_val, fb_rvalue);
*************** gimplify_expr (tree *expr_p, tree *pre_p
*** 3530,3534 ****
      {
        if (is_statement)
! 	*expr_p = build_empty_stmt ();
        goto out;
      }
--- 3812,3816 ----
      {
        if (is_statement)
! 	*expr_p = alloc_stmt_list ();
        goto out;
      }
*************** gimplify_expr (tree *expr_p, tree *pre_p
*** 3542,3546 ****
  
    if (!*expr_p)
!     *expr_p = build_empty_stmt ();
    if (fallback == fb_none && !is_gimple_stmt (*expr_p))
      {
--- 3824,3828 ----
  
    if (!*expr_p)
!     *expr_p = alloc_stmt_list ();
    if (fallback == fb_none && !is_gimple_stmt (*expr_p))
      {
*************** gimplify_expr (tree *expr_p, tree *pre_p
*** 3548,3556 ****
  	 statement.  If it doesn't have side-effects, throw it away.  */
        if (!TREE_SIDE_EFFECTS (*expr_p))
! 	*expr_p = build_empty_stmt ();
        else if (!TREE_THIS_VOLATILE (*expr_p))
! 	/* We only handle volatiles here; anything else with side-effects
! 	   must be converted to a valid statement before we get here.  */
! 	abort ();
        else if (COMPLETE_TYPE_P (TREE_TYPE (*expr_p)))
  	{
--- 3830,3858 ----
  	 statement.  If it doesn't have side-effects, throw it away.  */
        if (!TREE_SIDE_EFFECTS (*expr_p))
! 	*expr_p = alloc_stmt_list ();
        else if (!TREE_THIS_VOLATILE (*expr_p))
! 	{
! 	  /* This is probably a _REF that contains something nested that
! 	     has side effects.  Recurse through the operands to find it.  */
! 	  enum tree_code code = TREE_CODE (*expr_p);
! 
! 	  if (code == COMPONENT_REF
! 	      || code == REALPART_EXPR || code == IMAGPART_EXPR)
! 	    gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
! 			   gimple_test_f, fallback);
! 	  else if (code == ARRAY_REF || code == ARRAY_RANGE_REF)
! 	    {
! 	      gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
! 			     gimple_test_f, fallback);
! 	      gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p, post_p,
! 			   gimple_test_f, fallback);
! 	    }
! 	  else
! 	    /* Anything else with side-effects
! 	       must be converted to a valid statement before we get here.  */
! 	    abort ();
! 
! 	  *expr_p = alloc_stmt_list ();
! 	}
        else if (COMPLETE_TYPE_P (TREE_TYPE (*expr_p)))
  	{
*************** gimplify_expr (tree *expr_p, tree *pre_p
*** 3563,3567 ****
  	/* We can't do anything useful with a volatile reference to
  	   incomplete type, so just throw it away.  */
! 	*expr_p = build_empty_stmt ();
      }
  
--- 3865,3869 ----
  	/* We can't do anything useful with a volatile reference to
  	   incomplete type, so just throw it away.  */
! 	*expr_p = alloc_stmt_list ();
      }
  
*************** gimplify_expr (tree *expr_p, tree *pre_p
*** 3661,3664 ****
--- 3963,4038 ----
  }
  
+ /* Look through TYPE for variable-sized objects and gimplify each such
+    size that we find.  Return a STATEMENT_LIST containing the result.  */
+ 
+ tree
+ gimplify_type_sizes (tree type)
+ {
+   tree stmts = NULL_TREE;
+   tree field;
+ 
+   switch (TREE_CODE (type))
+     {
+     case ERROR_MARK:
+       return alloc_stmt_list ();
+ 
+     case INTEGER_TYPE:
+     case ENUMERAL_TYPE:
+     case BOOLEAN_TYPE:
+     case CHAR_TYPE:
+     case REAL_TYPE:
+       gimplify_one_sizepos (&TYPE_MIN_VALUE (type), &stmts);
+       gimplify_one_sizepos (&TYPE_MAX_VALUE (type), &stmts);
+       break;
+ 
+     case ARRAY_TYPE:
+       /* These anonymous types don't have declarations, so handle them here. */
+       append_to_statement_list (gimplify_type_sizes (TYPE_DOMAIN (type)),
+ 				&stmts);
+       break;
+ 
+     case RECORD_TYPE:
+     case UNION_TYPE:
+     case QUAL_UNION_TYPE:
+       for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
+ 	if (TREE_CODE (field) == FIELD_DECL)
+ 	  gimplify_one_sizepos (&DECL_FIELD_OFFSET (field), &stmts);
+       break;
+ 
+     default:
+       break;
+     }
+ 
+   gimplify_one_sizepos (&TYPE_SIZE (type), &stmts);
+   gimplify_one_sizepos (&TYPE_SIZE_UNIT (type), &stmts);
+ 
+   if (!stmts)
+     stmts = alloc_stmt_list ();
+ 
+   return stmts;
+ }
+ 
+ /* Subroutine of the above to gimplify one size or position, *EXPR_P.
+    We add any required statements to STMT_P.  */
+ 
+ void
+ gimplify_one_sizepos (tree *expr_p, tree *stmt_p)
+ {
+   tree pre = NULL_TREE, post = NULL_TREE;
+ 
+   /* We don't do anything if the value isn't there, is constant, or contains
+      A PLACEHOLDER_EXPR.  */
+   if (*expr_p == NULL_TREE || TREE_CONSTANT (*expr_p)
+       || CONTAINS_PLACEHOLDER_P (*expr_p))
+     return;
+ 
+   gimplify_expr (expr_p, &pre, &post, is_gimple_val, fb_rvalue);
+ 
+   if (pre)
+     append_to_statement_list (pre, stmt_p);
+   if (post)
+     append_to_statement_list (post, stmt_p);
+ }
+ \f
  #ifdef ENABLE_CHECKING
  /* Compare types A and B for a "close enough" match.  */
*************** check_pointer_types_r (tree *tp, int *wa
*** 3721,3726 ****
        if (!cpt_same_type (otype, dtype))
  	{
! 	  /* &array is allowed to produce a pointer to the element,
! 	     rather than a pointer to the array type.  */
  	  if (TREE_CODE (otype) == ARRAY_TYPE
  	      && POINTER_TYPE_P (ptype)
--- 4095,4102 ----
        if (!cpt_same_type (otype, dtype))
  	{
! 	  /* &array is allowed to produce a pointer to the element, rather than
! 	     a pointer to the array type.  We must allow this in order to
! 	     properly represent assigning the address of an array in C into
! 	     pointer to the element type.  */
  	  if (TREE_CODE (otype) == ARRAY_TYPE
  	      && POINTER_TYPE_P (ptype)
*************** gimplify_body (tree *body_p, tree fndecl
*** 3752,3757 ****
    push_gimplify_context ();
  
!   /* Unshare most shared trees in the body.  */
!   unshare_all_trees (*body_p);
  
    /* Make sure input_location isn't set to something wierd.  */
--- 4128,4137 ----
    push_gimplify_context ();
  
!   /* Unshare most shared trees in the body and in that of any nested functions.
!      It would seem we don't have to do this for nested functions because
!      they are supposed to be output and then the outer function gimplified
!      first, but the g++ front end doesn't always do it that way.  */
!   unshare_body (body_p, fndecl);
!   unvisit_body (body_p, fndecl);
  
    /* Make sure input_location isn't set to something wierd.  */
*** stmt.c	20 Jun 2004 17:16:26 -0000	1.361
--- stmt.c	21 Jun 2004 22:50:27 -0000
*************** expand_stack_alloc (tree alloc, tree t_s
*** 3392,3401 ****
    type = TREE_TYPE (var);
  
-   /* In function-at-a-time mode, variable_size doesn't expand this,
-      so do it now.  */
-   if (TREE_CODE (type) == ARRAY_TYPE && TYPE_DOMAIN (type))
-     expand_expr (TYPE_MAX_VALUE (TYPE_DOMAIN (type)),
- 		 const0_rtx, VOIDmode, 0);
- 
    /* Compute the variable's size, in bytes.  */
    size = expand_expr (t_size, NULL_RTX, VOIDmode, 0);
--- 3392,3395 ----
*** stor-layout.c	28 May 2004 23:12:14 -0000	1.191
--- stor-layout.c	21 Jun 2004 22:50:28 -0000
*************** get_pending_sizes (void)
*** 94,102 ****
  {
    tree chain = pending_sizes;
-   tree t;
- 
-   /* Put each SAVE_EXPR into the current function.  */
-   for (t = chain; t; t = TREE_CHAIN (t))
-     SAVE_EXPR_CONTEXT (TREE_VALUE (t)) = current_function_decl;
  
    pending_sizes = 0;
--- 94,97 ----
*** tree-alias-common.c	17 Jun 2004 05:13:25 -0000	2.4
--- tree-alias-common.c	21 Jun 2004 22:50:29 -0000
*************** get_alias_var (tree expr)
*** 208,217 ****
      {
      case ARRAY_REF:
        {
! 	/* Find the first non-array ref, and return it's alias
! 	   variable */
  	tree p;
! 	for (p = expr; TREE_CODE (p) == ARRAY_REF;
! 	     p = TREE_OPERAND (p, 0));
  	return get_alias_var (p);
        }
--- 208,220 ----
      {
      case ARRAY_REF:
+     case ARRAY_RANGE_REF:
        {
! 	/* Find the first non-array ref, and return its alias variable.  */
  	tree p;
! 
! 	for (p = expr;
! 	     TREE_CODE (p) == ARRAY_REF || TREE_CODE (p) == ARRAY_RANGE_REF;
! 	     p = TREE_OPERAND (p, 0))
! 	  ;
  	return get_alias_var (p);
        }
*** tree-cfg.c	19 Jun 2004 18:52:04 -0000	2.17
--- tree-cfg.c	21 Jun 2004 22:50:30 -0000
*************** verify_expr (tree *tp, int *walk_subtree
*** 3157,3166 ****
  
      case ADDR_EXPR:
!       x = TREE_OPERAND (t, 0);
!       while (TREE_CODE (x) == ARRAY_REF
! 	     || TREE_CODE (x) == COMPONENT_REF
! 	     || TREE_CODE (x) == REALPART_EXPR
! 	     || TREE_CODE (x) == IMAGPART_EXPR)
! 	x = TREE_OPERAND (x, 0);
        if (TREE_CODE (x) != VAR_DECL && TREE_CODE (x) != PARM_DECL)
  	return NULL;
--- 3157,3164 ----
  
      case ADDR_EXPR:
!       for (x = TREE_OPERAND (t, 0); handled_component_p (x);
! 	   x = TREE_OPERAND (x, 0))
! 	;
! 
        if (TREE_CODE (x) != VAR_DECL && TREE_CODE (x) != PARM_DECL)
  	return NULL;
*************** tree_node_can_be_shared (tree t)
*** 3310,3314 ****
      return true;
  
!   while ((TREE_CODE (t) == ARRAY_REF
  	  /* We check for constants explicitly since they are not considered
  	     gimple invariants if they overflowed.  */
--- 3308,3312 ----
      return true;
  
!   while (((TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF)
  	  /* We check for constants explicitly since they are not considered
  	     gimple invariants if they overflowed.  */
*** tree-dfa.c	18 Jun 2004 14:05:19 -0000	2.11
--- tree-dfa.c	21 Jun 2004 22:50:31 -0000
*************** tree
*** 927,932 ****
  get_virtual_var (tree var)
  {
-   enum tree_code code;
- 
    STRIP_NOPS (var);
  
--- 927,930 ----
*************** get_virtual_var (tree var)
*** 934,948 ****
      var = SSA_NAME_VAR (var);
  
!   code = TREE_CODE (var);
! 
!   while (code == ARRAY_REF
!          || code == COMPONENT_REF
! 	 || code == REALPART_EXPR
! 	 || code == IMAGPART_EXPR)
!     {
        var = TREE_OPERAND (var, 0);
!       code = TREE_CODE (var);
!     }
! 
  #ifdef ENABLE_CHECKING
    /* Treating GIMPLE registers as virtual variables makes no sense.
--- 932,941 ----
      var = SSA_NAME_VAR (var);
  
!   if (TREE_CODE (var) == REALPART_EXPR || TREE_CODE (var) == IMAGPART_EXPR)
!     var = TREE_OPERAND (var, 0);
!   else
!     while (handled_component_p (var))
        var = TREE_OPERAND (var, 0);
!     
  #ifdef ENABLE_CHECKING
    /* Treating GIMPLE registers as virtual variables makes no sense.
*** tree-dump.c	21 May 2004 19:50:49 -0000	1.22
--- tree-dump.c	21 Jun 2004 22:50:31 -0000
*************** dequeue_and_dump (dump_info_p di)
*** 537,543 ****
      case INIT_EXPR:
      case MODIFY_EXPR:
-     case COMPONENT_REF:
      case COMPOUND_EXPR:
-     case ARRAY_REF:
      case PREDECREMENT_EXPR:
      case PREINCREMENT_EXPR:
--- 537,541 ----
*************** dequeue_and_dump (dump_info_p di)
*** 549,552 ****
--- 547,564 ----
        break;
  
+     case COMPONENT_REF:
+       dump_child ("op 0", TREE_OPERAND (t, 0));
+       dump_child ("op 1", TREE_OPERAND (t, 1));
+       dump_child ("op 2", TREE_OPERAND (t, 2));
+       break;
+ 
+     case ARRAY_REF:
+     case ARRAY_RANGE_REF:
+       dump_child ("op 0", TREE_OPERAND (t, 0));
+       dump_child ("op 1", TREE_OPERAND (t, 1));
+       dump_child ("op 2", TREE_OPERAND (t, 2));
+       dump_child ("op 3", TREE_OPERAND (t, 3));
+       break;
+ 
      case COND_EXPR:
        dump_child ("op 0", TREE_OPERAND (t, 0));
*** tree-eh.c	18 Jun 2004 22:32:49 -0000	2.5
--- tree-eh.c	21 Jun 2004 22:50:32 -0000
*************** tree_could_trap_p (tree expr)
*** 1683,1686 ****
--- 1683,1687 ----
      {
      case ARRAY_REF:
+     case ARRAY_RANGE_REF:
      case COMPONENT_REF:
      case REALPART_EXPR:
*** tree-gimple.c	8 Jun 2004 16:29:57 -0000	2.5
--- tree-gimple.c	21 Jun 2004 22:50:32 -0000
*************** Boston, MA 02111-1307, USA.  */
*** 120,134 ****
     bitfieldref :
       BIT_FIELD_REF
!        op0 -> compref | min-lval
         op1 -> CONST
!        op2 -> CONST
     compref :
       COMPONENT_REF
!        op0 -> compref | min-lval
       | ARRAY_REF
!        op0 -> compref | min-lval
         op1 -> val
       | REALPART_EXPR
       | IMAGPART_EXPR
  
     condition : val | val relop val
--- 120,151 ----
     bitfieldref :
       BIT_FIELD_REF
!        op0 -> inner_compref
         op1 -> CONST
!        op2 -> var
     compref :
       COMPONENT_REF
!        op0 -> inner_compref
       | ARRAY_REF
!        op0 -> inner_compref
         op1 -> val
+        op2 -> val
+        op3 -> val
+      | ARRAY_RANGE_REF
+        op0 -> inner_compref
+        op1 -> val
+        op2 -> val
+        op3 -> val
       | REALPART_EXPR
+        op0 -> inner_compref
       | IMAGPART_EXPR
+        op0 -> inner_compref
+ 
+    inner_compref : compref | min_lval
+      | VIEW_CONVERT_EXPR
+        op0 -> inner_compref
+      | NOP_EXPR
+        op0 -> inner_compref
+      | CONVERT_EXPR
+        op0 -> inner_compref
  
     condition : val | val relop val
*************** is_gimple_addr_expr_arg (tree t)
*** 285,291 ****
    return (is_gimple_id (t)
  	  || TREE_CODE (t) == ARRAY_REF
  	  || TREE_CODE (t) == COMPONENT_REF
  	  || TREE_CODE (t) == REALPART_EXPR
! 	  || TREE_CODE (t) == IMAGPART_EXPR);
  }
  
--- 302,310 ----
    return (is_gimple_id (t)
  	  || TREE_CODE (t) == ARRAY_REF
+ 	  || TREE_CODE (t) == ARRAY_RANGE_REF
  	  || TREE_CODE (t) == COMPONENT_REF
  	  || TREE_CODE (t) == REALPART_EXPR
! 	  || TREE_CODE (t) == IMAGPART_EXPR
! 	  || TREE_CODE (t) == INDIRECT_REF);
  }
  
*************** get_base_address (tree t)
*** 582,598 ****
  	return t;
  
!       switch (TREE_CODE (t))
! 	{
! 	case ARRAY_REF:
! 	case COMPONENT_REF:
! 	case REALPART_EXPR:
! 	case IMAGPART_EXPR:
! 	case BIT_FIELD_REF:
! 	  t = TREE_OPERAND (t, 0);
! 	  break;
! 
! 	default:
! 	  return NULL_TREE;
! 	}
      }
    while (t);
--- 601,610 ----
  	return t;
  
!       if (TREE_CODE (t) == REALPART_EXPR || TREE_CODE (t) == IMAGPART_EXPR)
! 	t = TREE_OPERAND (t, 0);
!       else if (handled_component_p (t))
! 	t = get_base_address (TREE_OPERAND (t, 0));
!       else
! 	return NULL_TREE;
      }
    while (t);
*** tree-gimple.h	16 Jun 2004 01:21:26 -0000	2.6
--- tree-gimple.h	21 Jun 2004 22:50:33 -0000
*************** extern void annotate_all_with_locus (tre
*** 43,85 ****
  
  /* Returns true iff T is a valid GIMPLE statement.  */
! bool is_gimple_stmt (tree);
  
  /* Returns true iff TYPE is a valid type for a scalar register variable.  */
! bool is_gimple_reg_type (tree);
  /* Returns true iff T is a scalar register variable.  */
! bool is_gimple_reg (tree);
  /* Returns true iff T is any sort of variable.  */
! bool is_gimple_variable (tree);
  /* Returns true iff T is a variable or an INDIRECT_REF (of a variable).  */
! bool is_gimple_min_lval (tree);
  /* Returns true iff T is an lvalue other than an INDIRECT_REF.  */
! bool is_gimple_addr_expr_arg (tree);
  /* Returns true iff T is any valid GIMPLE lvalue.  */
! bool is_gimple_lvalue (tree);
  
  /* Returns true iff T is a GIMPLE restricted function invariant.  */
! bool is_gimple_min_invariant (tree);
  /* Returns true iff T is a GIMPLE rvalue.  */
! bool is_gimple_val (tree);
  /* Returns true iff T is a valid rhs for a MODIFY_EXPR.  */
! bool is_gimple_rhs (tree);
  
  /* Returns true iff T is a valid if-statement condition.  */
! bool is_gimple_condexpr (tree);
  
  /* Returns true iff T is a type conversion.  */
! bool is_gimple_cast (tree);
  /* Returns true iff T is a valid CONSTRUCTOR element (either an rvalue or
     another CONSTRUCTOR).  */
! bool is_gimple_constructor_elt (tree);
  /* Returns true iff T is a variable that does not need to live in memory.  */
! bool is_gimple_non_addressable (tree t);
  
  /* If T makes a function call, returns the CALL_EXPR operand.  */
! tree get_call_expr_in (tree t);
  
! void recalculate_side_effects (tree);
  
! void append_to_compound_expr (tree, tree *);
  
  /* FIXME we should deduce this from the predicate.  */
--- 43,85 ----
  
  /* Returns true iff T is a valid GIMPLE statement.  */
! extern bool is_gimple_stmt (tree);
  
  /* Returns true iff TYPE is a valid type for a scalar register variable.  */
! extern bool is_gimple_reg_type (tree);
  /* Returns true iff T is a scalar register variable.  */
! extern bool is_gimple_reg (tree);
  /* Returns true iff T is any sort of variable.  */
! extern bool is_gimple_variable (tree);
  /* Returns true iff T is a variable or an INDIRECT_REF (of a variable).  */
! extern bool is_gimple_min_lval (tree);
  /* Returns true iff T is an lvalue other than an INDIRECT_REF.  */
! extern bool is_gimple_addr_expr_arg (tree);
  /* Returns true iff T is any valid GIMPLE lvalue.  */
! extern bool is_gimple_lvalue (tree);
  
  /* Returns true iff T is a GIMPLE restricted function invariant.  */
! extern bool is_gimple_min_invariant (tree);
  /* Returns true iff T is a GIMPLE rvalue.  */
! extern bool is_gimple_val (tree);
  /* Returns true iff T is a valid rhs for a MODIFY_EXPR.  */
! extern bool is_gimple_rhs (tree);
  
  /* Returns true iff T is a valid if-statement condition.  */
! extern bool is_gimple_condexpr (tree);
  
  /* Returns true iff T is a type conversion.  */
! extern bool is_gimple_cast (tree);
  /* Returns true iff T is a valid CONSTRUCTOR element (either an rvalue or
     another CONSTRUCTOR).  */
! extern bool is_gimple_constructor_elt (tree);
  /* Returns true iff T is a variable that does not need to live in memory.  */
! extern bool is_gimple_non_addressable (tree t);
  
  /* If T makes a function call, returns the CALL_EXPR operand.  */
! extern tree get_call_expr_in (tree t);
  
! extern void recalculate_side_effects (tree);
  
! extern void append_to_compound_expr (tree, tree *);
  
  /* FIXME we should deduce this from the predicate.  */
*************** enum gimplify_status {
*** 99,125 ****
  };
  
! enum gimplify_status gimplify_expr (tree *, tree *, tree *,
! 				    bool (*) (tree), fallback_t);
! void gimplify_stmt (tree *);
! void gimplify_to_stmt_list (tree *);
! void gimplify_body (tree *, tree);
! void push_gimplify_context (void);
! void pop_gimplify_context (tree);
! void gimplify_and_add (tree, tree *);
  
  /* Miscellaneous helpers.  */
! tree get_base_address (tree t);
! void gimple_add_tmp_var (tree);
! tree gimple_current_bind_expr (void);
! void gimple_push_bind_expr (tree);
! void gimple_pop_bind_expr (void);
! void unshare_all_trees (tree);
! tree voidify_wrapper_expr (tree, tree);
! tree gimple_build_eh_filter (tree, tree, tree);
! tree build_and_jump (tree *);
! tree alloc_stmt_list (void);
! void free_stmt_list (tree);
! tree force_labels_r (tree *, int *, void *);
! enum gimplify_status gimplify_va_arg_expr (tree *, tree *, tree *);
  
  /* In tree-nested.c.  */
--- 99,127 ----
  };
  
! extern enum gimplify_status gimplify_expr (tree *, tree *, tree *,
! 					   bool (*) (tree), fallback_t);
! extern tree gimplify_type_sizes (tree);
! extern void gimplify_one_sizepos (tree *, tree *);
! extern void gimplify_stmt (tree *);
! extern void gimplify_to_stmt_list (tree *);
! extern void gimplify_body (tree *, tree);
! extern void push_gimplify_context (void);
! extern void pop_gimplify_context (tree);
! extern void gimplify_and_add (tree, tree *);
  
  /* Miscellaneous helpers.  */
! extern tree get_base_address (tree t);
! extern void gimple_add_tmp_var (tree);
! extern tree gimple_current_bind_expr (void);
! extern void gimple_push_bind_expr (tree);
! extern void gimple_pop_bind_expr (void);
! extern void unshare_all_trees (tree);
! extern tree voidify_wrapper_expr (tree, tree);
! extern tree gimple_build_eh_filter (tree, tree, tree);
! extern tree build_and_jump (tree *);
! extern tree alloc_stmt_list (void);
! extern void free_stmt_list (tree);
! extern tree force_labels_r (tree *, int *, void *);
! extern enum gimplify_status gimplify_va_arg_expr (tree *, tree *, tree *);
  
  /* In tree-nested.c.  */
*** tree-inline.c	21 Jun 2004 09:15:21 -0000	1.110
--- tree-inline.c	21 Jun 2004 22:50:34 -0000
*************** walk_tree (tree *tp, walk_tree_fn func, 
*** 2055,2060 ****
  #endif
      }
!   else if (TREE_CODE_CLASS (code) == 'd')
      {
        WALK_SUBTREE_TAIL (TREE_TYPE (*tp));
      }
--- 2055,2066 ----
  #endif
      }
! 
!   /* Look inside the sizes of decls, but we don't ever use the values for
!      FIELD_DECL and RESULT_DECL, so ignore them.  */
!   else if (TREE_CODE_CLASS (code) == 'd'
! 	   && code != FIELD_DECL && code != RESULT_DECL)
      {
+       WALK_SUBTREE (DECL_SIZE (*tp));
+       WALK_SUBTREE (DECL_SIZE_UNIT (*tp));
        WALK_SUBTREE_TAIL (TREE_TYPE (*tp));
      }
*************** walk_tree (tree *tp, walk_tree_fn func, 
*** 2078,2092 ****
  	case VECTOR_CST:
  	case STRING_CST:
- 	case REAL_TYPE:
- 	case COMPLEX_TYPE:
  	case VECTOR_TYPE:
  	case VOID_TYPE:
- 	case BOOLEAN_TYPE:
- 	case UNION_TYPE:
- 	case ENUMERAL_TYPE:
  	case BLOCK:
- 	case RECORD_TYPE:
  	case PLACEHOLDER_EXPR:
  	case SSA_NAME:
  	  /* None of thse have subtrees other than those already walked
  	     above.  */
--- 2084,2094 ----
  	case VECTOR_CST:
  	case STRING_CST:
  	case VECTOR_TYPE:
  	case VOID_TYPE:
  	case BLOCK:
  	case PLACEHOLDER_EXPR:
  	case SSA_NAME:
+ 	case FIELD_DECL:
+ 	case RESULT_DECL:
  	  /* None of thse have subtrees other than those already walked
  	     above.  */
*************** walk_tree (tree *tp, walk_tree_fn func, 
*** 2095,2098 ****
--- 2097,2101 ----
  	case POINTER_TYPE:
  	case REFERENCE_TYPE:
+ 	case COMPLEX_TYPE:
  	  WALK_SUBTREE_TAIL (TREE_TYPE (*tp));
  	  break;
*************** walk_tree (tree *tp, walk_tree_fn func, 
*** 2127,2130 ****
--- 2130,2134 ----
  	case METHOD_TYPE:
  	  WALK_SUBTREE (TYPE_METHOD_BASETYPE (*tp));
+ 
  	  /* Fall through.  */
  
*************** walk_tree (tree *tp, walk_tree_fn func, 
*** 2140,2149 ****
  	  break;
  
  	case ARRAY_TYPE:
! 	  WALK_SUBTREE (TREE_TYPE (*tp));
  	  WALK_SUBTREE_TAIL (TYPE_DOMAIN (*tp));
  
  	case INTEGER_TYPE:
  	case CHAR_TYPE:
  	  WALK_SUBTREE (TYPE_MIN_VALUE (*tp));
  	  WALK_SUBTREE_TAIL (TYPE_MAX_VALUE (*tp));
--- 2144,2184 ----
  	  break;
  
+ 	case RECORD_TYPE:
+ 	case UNION_TYPE:
+ 	case QUAL_UNION_TYPE:
+ 	  {
+ 	    tree field;
+ 
+ 	    for (field = TYPE_FIELDS (*tp); field; field = TREE_CHAIN (field))
+ 	      {
+ 		/* We would like to look at the type of the field, but we
+ 		   can easily get infinite recursion.  So assume it's
+ 		   pointed to elsewhere in the tree.  Also, ignore things that
+ 		   aren't fields.  */
+ 		if (TREE_CODE (field) != FIELD_DECL)
+ 		  continue;
+ 
+ 		WALK_SUBTREE (DECL_FIELD_OFFSET (field));
+ 		WALK_SUBTREE (DECL_SIZE (field));
+ 		WALK_SUBTREE (DECL_SIZE_UNIT (field));
+ 		if (code == QUAL_UNION_TYPE)
+ 		  WALK_SUBTREE (DECL_QUALIFIER (field));
+ 	      }
+ 	  }
+ 	  break;
+ 
  	case ARRAY_TYPE:
! 	  /* Don't follow this nodes's type if a pointer for fear that we'll
! 	     have infinite recursion.  Those types are uninteresting anyway. */
! 	  if (!POINTER_TYPE_P (TREE_TYPE (*tp))
! 	      && TREE_CODE (TREE_TYPE (*tp)) != OFFSET_TYPE)
! 	    WALK_SUBTREE (TREE_TYPE (*tp));
  	  WALK_SUBTREE_TAIL (TYPE_DOMAIN (*tp));
  
+ 	case BOOLEAN_TYPE:
+ 	case ENUMERAL_TYPE:
  	case INTEGER_TYPE:
  	case CHAR_TYPE:
+ 	case REAL_TYPE:
  	  WALK_SUBTREE (TYPE_MIN_VALUE (*tp));
  	  WALK_SUBTREE_TAIL (TYPE_MAX_VALUE (*tp));
*************** walk_tree (tree *tp, walk_tree_fn func, 
*** 2167,2172 ****
  		   into declarations that are just mentioned, rather than
  		   declared; they don't really belong to this part of the tree.
! 		   And, we can see cycles: the initializer for a declaration can
! 		   refer to the declaration itself.  */
  		WALK_SUBTREE (DECL_INITIAL (decl));
  		WALK_SUBTREE (DECL_SIZE (decl));
--- 2202,2207 ----
  		   into declarations that are just mentioned, rather than
  		   declared; they don't really belong to this part of the tree.
! 		   And, we can see cycles: the initializer for a declaration
! 		   can refer to the declaration itself.  */
  		WALK_SUBTREE (DECL_INITIAL (decl));
  		WALK_SUBTREE (DECL_SIZE (decl));
*************** walk_tree (tree *tp, walk_tree_fn func, 
*** 2186,2190 ****
  
  	default:
! 	  abort ();
  	}
      }
--- 2221,2227 ----
  
  	default:
! 	  /* ??? This could be a language-defined node.  We really should make
! 	     a hook for it, but right now just ignore it.  */
! 	  break;
  	}
      }
*** tree-mudflap.c	19 Jun 2004 15:33:06 -0000	2.7
--- tree-mudflap.c	21 Jun 2004 22:50:34 -0000
*************** mf_build_check_statement_for (tree addr,
*** 464,468 ****
    t = build (ARRAY_REF,
               TREE_TYPE (TREE_TYPE (mf_cache_array_decl)),
!              mf_cache_array_decl, t);
    t = build1 (ADDR_EXPR, mf_cache_structptr_type, t);
    t = build (MODIFY_EXPR, void_type_node, mf_elem, t);
--- 464,468 ----
    t = build (ARRAY_REF,
               TREE_TYPE (TREE_TYPE (mf_cache_array_decl)),
!              mf_cache_array_decl, t, NULL_TREE, NULL_TREE);
    t = build1 (ADDR_EXPR, mf_cache_structptr_type, t);
    t = build (MODIFY_EXPR, void_type_node, mf_elem, t);
*************** mf_build_check_statement_for (tree addr,
*** 488,492 ****
    t = build (COMPONENT_REF, mf_uintptr_type,
               build1 (INDIRECT_REF, mf_cache_struct_type, mf_elem),
!              TYPE_FIELDS (mf_cache_struct_type));
    t = build (GT_EXPR, boolean_type_node, t, mf_base);
  
--- 488,492 ----
    t = build (COMPONENT_REF, mf_uintptr_type,
               build1 (INDIRECT_REF, mf_cache_struct_type, mf_elem),
!              TYPE_FIELDS (mf_cache_struct_type), NULL_TREE);
    t = build (GT_EXPR, boolean_type_node, t, mf_base);
  
*************** mf_build_check_statement_for (tree addr,
*** 502,506 ****
    u = build (COMPONENT_REF, mf_uintptr_type,
               build1 (INDIRECT_REF, mf_cache_struct_type, mf_elem),
!              TREE_CHAIN (TYPE_FIELDS (mf_cache_struct_type)));
  
    v = convert (mf_uintptr_type,
--- 502,506 ----
    u = build (COMPONENT_REF, mf_uintptr_type,
               build1 (INDIRECT_REF, mf_cache_struct_type, mf_elem),
!              TREE_CHAIN (TYPE_FIELDS (mf_cache_struct_type)), NULL_TREE);
  
    v = convert (mf_uintptr_type,
*************** mf_xform_derefs_1 (block_stmt_iterator *
*** 661,672 ****
          if (DECL_BIT_FIELD_TYPE (field))
            {
!             size = bitsize_int (BITS_PER_UNIT);
!             size = size_binop (CEIL_DIV_EXPR, DECL_SIZE (field), size);
!             size = convert (sizetype, size);
  
              addr = TREE_OPERAND (TREE_OPERAND (t, 0), 0);
!             addr = convert (ptr_type_node, addr);
              addr = fold (build (PLUS_EXPR, ptr_type_node,
!                                 addr, byte_position (field)));
            }
          else
--- 661,672 ----
          if (DECL_BIT_FIELD_TYPE (field))
            {
! 	    if (TREE_CODE (DECL_SIZE_UNIT (field)) == INTEGER_CST)
! 	      size = DECL_SIZE_UNIT (field);
  
              addr = TREE_OPERAND (TREE_OPERAND (t, 0), 0);
!             addr = fold_convert (ptr_type_node, addr);
              addr = fold (build (PLUS_EXPR, ptr_type_node,
!                                 addr, fold_convert (ptr_type_node,
! 						    byte_position (field))));
            }
          else
*** tree-nested.c	30 May 2004 07:12:55 -0000	2.4
--- tree-nested.c	21 Jun 2004 22:50:35 -0000
*************** build_addr (tree exp)
*** 158,163 ****
  {
    tree base = exp;
!   while (TREE_CODE (base) == COMPONENT_REF || TREE_CODE (base) == ARRAY_REF)
      base = TREE_OPERAND (base, 0);
    if (DECL_P (base))
      TREE_ADDRESSABLE (base) = 1;
--- 158,168 ----
  {
    tree base = exp;
! 
!   if (TREE_CODE (base) == REALPART_EXPR || TREE_CODE (base) == IMAGPART_EXPR)
      base = TREE_OPERAND (base, 0);
+   else
+     while (handled_component_p (base))
+       base = TREE_OPERAND (base, 0);
+ 
    if (DECL_P (base))
      TREE_ADDRESSABLE (base) = 1;
*************** walk_stmts (struct walk_stmt_info *wi, t
*** 551,554 ****
--- 556,560 ----
      case CATCH_EXPR:
        walk_stmts (wi, &CATCH_BODY (t));
+       break;
      case EH_FILTER_EXPR:
        walk_stmts (wi, &EH_FILTER_FAILURE (t));
*************** get_static_chain (struct nesting_info *i
*** 658,662 ****
  
  	  x = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (x)), x);
! 	  x = build (COMPONENT_REF, TREE_TYPE (field), x, field);
  	  x = init_tmp_var (info, x, tsi);
  	}
--- 664,668 ----
  
  	  x = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (x)), x);
! 	  x = build (COMPONENT_REF, TREE_TYPE (field), x, field, NULL_TREE);
  	  x = init_tmp_var (info, x, tsi);
  	}
*************** get_frame_field (struct nesting_info *in
*** 692,696 ****
  
  	  x = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (x)), x);
! 	  x = build (COMPONENT_REF, TREE_TYPE (field), x, field);
  	  x = init_tmp_var (info, x, tsi);
  	}
--- 698,702 ----
  
  	  x = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (x)), x);
! 	  x = build (COMPONENT_REF, TREE_TYPE (field), x, field, NULL_TREE);
  	  x = init_tmp_var (info, x, tsi);
  	}
*************** get_frame_field (struct nesting_info *in
*** 699,703 ****
      }
  
!   x = build (COMPONENT_REF, TREE_TYPE (field), x, field);
    return x;
  }
--- 705,709 ----
      }
  
!   x = build (COMPONENT_REF, TREE_TYPE (field), x, field, NULL_TREE);
    return x;
  }
*************** convert_nonlocal_reference (tree *tp, in
*** 801,808 ****
--- 807,817 ----
  
      case ARRAY_REF:
+     case ARRAY_RANGE_REF:
        wi->val_only = false;
        walk_tree (&TREE_OPERAND (t, 0), convert_nonlocal_reference, wi, NULL);
        wi->val_only = true;
        walk_tree (&TREE_OPERAND (t, 1), convert_nonlocal_reference, wi, NULL);
+       walk_tree (&TREE_OPERAND (t, 2), convert_nonlocal_reference, wi, NULL);
+       walk_tree (&TREE_OPERAND (t, 3), convert_nonlocal_reference, wi, NULL);
        break;
  
*************** convert_local_reference (tree *tp, int *
*** 933,940 ****
--- 942,952 ----
  
      case ARRAY_REF:
+     case ARRAY_RANGE_REF:
        wi->val_only = false;
        walk_tree (&TREE_OPERAND (t, 0), convert_local_reference, wi, NULL);
        wi->val_only = true;
        walk_tree (&TREE_OPERAND (t, 1), convert_local_reference, wi, NULL);
+       walk_tree (&TREE_OPERAND (t, 2), convert_local_reference, wi, NULL);
+       walk_tree (&TREE_OPERAND (t, 3), convert_local_reference, wi, NULL);
        break;
  
*************** finalize_nesting_tree_1 (struct nesting_
*** 1243,1247 ****
  
  	  y = build (COMPONENT_REF, TREE_TYPE (field),
! 		     root->frame_decl, field);
  	  x = build (MODIFY_EXPR, TREE_TYPE (field), y, x);
  	  append_to_statement_list (x, &stmt_list);
--- 1255,1259 ----
  
  	  y = build (COMPONENT_REF, TREE_TYPE (field),
! 		     root->frame_decl, field, NULL_TREE);
  	  x = build (MODIFY_EXPR, TREE_TYPE (field), y, x);
  	  append_to_statement_list (x, &stmt_list);
*************** finalize_nesting_tree_1 (struct nesting_
*** 1253,1259 ****
    if (root->chain_field)
      {
!       tree x;
!       x = build (COMPONENT_REF, TREE_TYPE (root->chain_field),
! 		 root->frame_decl, root->chain_field);
        x = build (MODIFY_EXPR, TREE_TYPE (x), x, get_chain_decl (root));
        append_to_statement_list (x, &stmt_list);
--- 1265,1270 ----
    if (root->chain_field)
      {
!       tree x = build (COMPONENT_REF, TREE_TYPE (root->chain_field),
! 		      root->frame_decl, root->chain_field, NULL_TREE);
        x = build (MODIFY_EXPR, TREE_TYPE (x), x, get_chain_decl (root));
        append_to_statement_list (x, &stmt_list);
*************** finalize_nesting_tree_1 (struct nesting_
*** 1282,1286 ****
  
  	  x = build (COMPONENT_REF, TREE_TYPE (field),
! 		     root->frame_decl, field);
  	  x = build_addr (x);
  	  arg = tree_cons (NULL, x, arg);
--- 1293,1297 ----
  
  	  x = build (COMPONENT_REF, TREE_TYPE (field),
! 		     root->frame_decl, field, NULL_TREE);
  	  x = build_addr (x);
  	  arg = tree_cons (NULL, x, arg);
*** tree-outof-ssa.c	17 Jun 2004 18:13:15 -0000	2.8
--- tree-outof-ssa.c	21 Jun 2004 22:50:36 -0000
*************** discover_nonconstant_array_refs_r (tree 
*** 1764,1778 ****
    if (TYPE_P (t) || DECL_P (t))
      *walk_subtrees = 0;
!   else if (TREE_CODE (t) == ARRAY_REF)
      {
!       while ((TREE_CODE (t) == ARRAY_REF
  	      && is_gimple_min_invariant (TREE_OPERAND (t, 1)))
  	     || (TREE_CODE (t) == COMPONENT_REF
  		 || TREE_CODE (t) == BIT_FIELD_REF
  		 || TREE_CODE (t) == REALPART_EXPR
! 		 || TREE_CODE (t) == IMAGPART_EXPR))
  	t = TREE_OPERAND (t, 0);
  
!       if (TREE_CODE (t) == ARRAY_REF)
  	{
  	  t = get_base_address (t);
--- 1764,1781 ----
    if (TYPE_P (t) || DECL_P (t))
      *walk_subtrees = 0;
!   else if (TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF)
      {
!       while (((TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF)
  	      && is_gimple_min_invariant (TREE_OPERAND (t, 1)))
  	     || (TREE_CODE (t) == COMPONENT_REF
  		 || TREE_CODE (t) == BIT_FIELD_REF
  		 || TREE_CODE (t) == REALPART_EXPR
! 		 || TREE_CODE (t) == IMAGPART_EXPR
! 		 || TREE_CODE (t) == VIEW_CONVERT_EXPR
! 		 || TREE_CODE (t) == NOP_EXPR
! 		 || TREE_CODE (t) == CONVERT_EXPR))
  	t = TREE_OPERAND (t, 0);
  
!       if (TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF)
  	{
  	  t = get_base_address (t);
*** tree-pretty-print.c	16 Jun 2004 23:03:29 -0000	2.9
--- tree-pretty-print.c	21 Jun 2004 22:50:37 -0000
*************** dump_generic_node (pretty_printer *buffe
*** 393,396 ****
--- 393,397 ----
      case RECORD_TYPE:
      case UNION_TYPE:
+     case QUAL_UNION_TYPE:
        /* Print the name of the structure.  */
        if (TREE_CODE (node) == RECORD_TYPE)
*************** dump_generic_node (pretty_printer *buffe
*** 405,413 ****
        break;
  
-     case QUAL_UNION_TYPE:
-       NIY;
-       break;
- 
- 
      case LANG_TYPE:
        NIY;
--- 406,409 ----
*************** dump_generic_node (pretty_printer *buffe
*** 599,602 ****
--- 595,606 ----
        pp_string (buffer, str);
        dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
+       if (TREE_OPERAND (node, 2)
+ 	  && TREE_CODE (TREE_OPERAND (node, 2)) != INTEGER_CST)
+ 	{
+ 	  pp_string (buffer, "{off: ");
+ 	  dump_generic_node (buffer, TREE_OPERAND (node, 2),
+ 			     spc, flags, false);
+ 	  pp_character (buffer, '}');
+ 	}
        break;
  
*************** dump_generic_node (pretty_printer *buffe
*** 616,619 ****
--- 620,624 ----
  
      case ARRAY_REF:
+     case ARRAY_RANGE_REF:
        op0 = TREE_OPERAND (node, 0);
        if (op_prio (op0) < op_prio (node))
*************** dump_generic_node (pretty_printer *buffe
*** 624,632 ****
        pp_character (buffer, '[');
        dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
        pp_character (buffer, ']');
-       break;
  
!     case ARRAY_RANGE_REF:
!       NIY;
        break;
  
--- 629,649 ----
        pp_character (buffer, '[');
        dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
+       if (TREE_CODE (node) == ARRAY_RANGE_REF)
+ 	pp_string (buffer, " ...");
        pp_character (buffer, ']');
  
!       if ((TREE_OPERAND (node, 2)
! 	   && TREE_CODE (TREE_OPERAND (node, 2)) != INTEGER_CST)
! 	  || (TREE_OPERAND (node, 3)
! 	      && TREE_CODE (TREE_OPERAND (node, 3)) != INTEGER_CST))
! 	{
! 	  pp_string (buffer, "{lb: ");
! 	  dump_generic_node (buffer, TREE_OPERAND (node, 2),
! 			     spc, flags, false);
! 	  pp_string (buffer, " sz: ");
! 	  dump_generic_node (buffer, TREE_OPERAND (node, 3),
! 			     spc, flags, false);
! 	  pp_character (buffer, '}');
! 	}
        break;
  
*************** print_struct_decl (pretty_printer *buffe
*** 1491,1498 ****
        if (TREE_CODE (node) == RECORD_TYPE)
  	pp_string (buffer, "struct ");
!       else if (TREE_CODE (node) == UNION_TYPE)
  	pp_string (buffer, "union ");
!       else
! 	NIY;
        dump_generic_node (buffer, TYPE_NAME (node), spc, 0, false);
      }
--- 1508,1515 ----
        if (TREE_CODE (node) == RECORD_TYPE)
  	pp_string (buffer, "struct ");
!       else if ((TREE_CODE (node) == UNION_TYPE
! 		|| TREE_CODE (node) == QUAL_UNION_TYPE))
  	pp_string (buffer, "union ");
! 
        dump_generic_node (buffer, TYPE_NAME (node), spc, 0, false);
      }
*************** op_prio (tree op)
*** 1657,1660 ****
--- 1674,1678 ----
      case CALL_EXPR:
      case ARRAY_REF:
+     case ARRAY_RANGE_REF:
      case COMPONENT_REF:
        return 15;
*** tree-sra.c	19 Jun 2004 15:33:06 -0000	2.7
--- tree-sra.c	21 Jun 2004 22:50:37 -0000
*************** csc_build_component_ref (tree base, tree
*** 622,626 ****
      }
  
!   return build (COMPONENT_REF, TREE_TYPE (field), base, field);
  }
  
--- 622,626 ----
      }
  
!   return build (COMPONENT_REF, TREE_TYPE (field), base, field, NULL_TREE);
  }
  
*************** scalarize_call_expr (block_stmt_iterator
*** 1012,1016 ****
    if (TREE_CODE (stmt) == MODIFY_EXPR)
      {
!       tree var = TREE_OPERAND (stmt, 0);
  
        /* If the LHS of the assignment is a scalarizable structure, insert
--- 1012,1016 ----
    if (TREE_CODE (stmt) == MODIFY_EXPR)
      {
!       tree var = get_base_address (TREE_OPERAND (stmt, 0));
  
        /* If the LHS of the assignment is a scalarizable structure, insert
*** tree-ssa-ccp.c	18 Jun 2004 14:05:19 -0000	2.11
--- tree-ssa-ccp.c	21 Jun 2004 22:50:38 -0000
*************** tree
*** 1042,1056 ****
  widen_bitfield (tree val, tree field, tree var)
  {
!   unsigned var_size, field_size;
    tree wide_val;
    unsigned HOST_WIDE_INT mask;
!   unsigned i;
  
!   var_size = TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE ((var))));
!   field_size = TREE_INT_CST_LOW (DECL_SIZE (field));
  
    /* Give up if either the bitfield or the variable are too wide.  */
    if (field_size > HOST_BITS_PER_WIDE_INT || var_size > HOST_BITS_PER_WIDE_INT)
!     return NULL;
  
  #if defined ENABLE_CHECKING
--- 1042,1063 ----
  widen_bitfield (tree val, tree field, tree var)
  {
!   unsigned HOST_WIDE_INT var_size, field_size;
    tree wide_val;
    unsigned HOST_WIDE_INT mask;
!   unsigned int i;
  
!   /* We can only do this if the size of the type and field and VAL are
!      all constants representable in HOST_WIDE_INT.  */
!   if (!host_integerp (TYPE_SIZE (TREE_TYPE (var)), 1)
!       || !host_integerp (DECL_SIZE (field), 1)
!       || !host_integerp (val, 0))
!     return NULL_TREE;
! 
!   var_size = tree_low_cst (TYPE_SIZE (TREE_TYPE (var)), 1);
!   field_size = tree_low_cst (DECL_SIZE (field), 1);
  
    /* Give up if either the bitfield or the variable are too wide.  */
    if (field_size > HOST_BITS_PER_WIDE_INT || var_size > HOST_BITS_PER_WIDE_INT)
!     return NULL_TREE;
  
  #if defined ENABLE_CHECKING
*************** widen_bitfield (tree val, tree field, tr
*** 1059,1070 ****
  #endif
  
!   /* If VAL is not an integer constant, then give up.  */
!   if (TREE_CODE (val) != INTEGER_CST)
!     return NULL;
! 
!   /* If the sign bit of the value is not set, or the field's type is
!      unsigned, then just mask off the high order bits of the value.  */
!   if ((TREE_INT_CST_LOW (val) & (1 << (field_size - 1))) == 0
!       || DECL_UNSIGNED (field))
      {
        /* Zero extension.  Build a mask with the lower 'field_size' bits
--- 1066,1073 ----
  #endif
  
!   /* If the sign bit of the value is not set or the field's type is unsigned,
!      just mask off the high order bits of the value.  */
!   if (DECL_UNSIGNED (field)
!       || !(tree_low_cst (val, 0) & (((HOST_WIDE_INT)1) << (field_size - 1))))
      {
        /* Zero extension.  Build a mask with the lower 'field_size' bits
*************** widen_bitfield (tree val, tree field, tr
*** 1072,1079 ****
  	 the value.  */
        for (i = 0, mask = 0; i < field_size; i++)
! 	mask |= 1 << i;
  
        wide_val = build (BIT_AND_EXPR, TREE_TYPE (var), val, 
! 			build_int_2 (mask, 0));
      }
    else
--- 1075,1082 ----
  	 the value.  */
        for (i = 0, mask = 0; i < field_size; i++)
! 	mask |= ((HOST_WIDE_INT) 1) << i;
  
        wide_val = build (BIT_AND_EXPR, TREE_TYPE (var), val, 
! 			fold_convert (TREE_TYPE (var), build_int_2 (mask, 0)));
      }
    else
*************** widen_bitfield (tree val, tree field, tr
*** 1083,1090 ****
  	 value.  */
        for (i = 0, mask = 0; i < (var_size - field_size); i++)
! 	mask |= 1 << (var_size - i - 1);
  
        wide_val = build (BIT_IOR_EXPR, TREE_TYPE (var), val,
! 			build_int_2 (mask, 0));
      }
  
--- 1086,1093 ----
  	 value.  */
        for (i = 0, mask = 0; i < (var_size - field_size); i++)
! 	mask |= ((HOST_WIDE_INT) 1) << (var_size - i - 1);
  
        wide_val = build (BIT_IOR_EXPR, TREE_TYPE (var), val,
! 			fold_convert (TREE_TYPE (var), build_int_2 (mask, 0)));
      }
  
*************** static tree
*** 1494,1501 ****
  maybe_fold_offset_to_array_ref (tree base, tree offset, tree orig_type)
  {
!   unsigned HOST_WIDE_INT lquo, lrem;
!   HOST_WIDE_INT hquo, hrem;
!   tree elt_size, min_idx, idx;
!   tree array_type, elt_type;
  
    /* Ignore stupid user tricks of indexing non-array variables.  */
--- 1497,1520 ----
  maybe_fold_offset_to_array_ref (tree base, tree offset, tree orig_type)
  {
!   tree min_idx, idx, elt_offset = integer_zero_node;
!   tree array_type, elt_type, elt_size;
! 
!   /* If BASE is an ARRAY_REF, we can pick up another offset (this time
!      measured in units of the size of elements type) from that ARRAY_REF).
!      We can't do anything if either is variable.
! 
!      The case we handle here is *(&A[N]+O).  */
!   if (TREE_CODE (base) == ARRAY_REF)
!     {
!       tree low_bound = array_ref_low_bound (base);
! 
!       elt_offset = TREE_OPERAND (base, 1);
!       if (TREE_CODE (low_bound) != INTEGER_CST
! 	  || TREE_CODE (elt_offset) != INTEGER_CST)
! 	return NULL_TREE;
! 
!       elt_offset = int_const_binop (MINUS_EXPR, elt_offset, low_bound, 0);
!       base = TREE_OPERAND (base, 0);
!     }
  
    /* Ignore stupid user tricks of indexing non-array variables.  */
*************** maybe_fold_offset_to_array_ref (tree bas
*** 1507,1541 ****
      return NULL_TREE;
  	
!   /* Whee.  Ignore indexing of variable sized types.  */
    elt_size = TYPE_SIZE_UNIT (elt_type);
!   if (TREE_CODE (elt_size) != INTEGER_CST)
!     return NULL_TREE;
  
!   /* If the division isn't exact, then don't do anything.  Equally
!      invalid as the above indexing of non-array variables.  */
!   if (div_and_round_double (TRUNC_DIV_EXPR, 1,
! 			    TREE_INT_CST_LOW (offset),
! 			    TREE_INT_CST_HIGH (offset),
! 			    TREE_INT_CST_LOW (elt_size),
! 			    TREE_INT_CST_HIGH (elt_size),
! 			    &lquo, &hquo, &lrem, &hrem)
!       || lrem || hrem)
!     return NULL_TREE;
!   idx = build_int_2_wide (lquo, hquo);
  
!   /* Re-bias the index by the min index of the array type.  */
!   min_idx = TYPE_DOMAIN (TREE_TYPE (base));
!   if (min_idx)
      {
!       min_idx = TYPE_MIN_VALUE (min_idx);
!       if (min_idx)
! 	{
! 	  idx = convert (TREE_TYPE (min_idx), idx);
! 	  if (!integer_zerop (min_idx))
! 	    idx = int_const_binop (PLUS_EXPR, idx, min_idx, 1);
! 	}
      }
  
!   return build (ARRAY_REF, orig_type, base, idx);
  }
  
--- 1526,1585 ----
      return NULL_TREE;
  	
!   /* If OFFSET and ELT_OFFSET are zero, we don't care about the size of the
!      element type (so we can use the alignment if it's not constant).
!      Otherwise, compute the offset as an index by using a division.  If the
!      division isn't exact, then don't do anything.  */
    elt_size = TYPE_SIZE_UNIT (elt_type);
!   if (integer_zerop (offset))
!     {
!       if (TREE_CODE (elt_size) != INTEGER_CST)
! 	elt_size = size_int (TYPE_ALIGN (elt_type));
  
!       idx = integer_zero_node;
!     }
!   else
!     {
!       unsigned HOST_WIDE_INT lquo, lrem;
!       HOST_WIDE_INT hquo, hrem;
! 
!       if (TREE_CODE (elt_size) != INTEGER_CST
! 	  || div_and_round_double (TRUNC_DIV_EXPR, 1,
! 				   TREE_INT_CST_LOW (offset),
! 				   TREE_INT_CST_HIGH (offset),
! 				   TREE_INT_CST_LOW (elt_size),
! 				   TREE_INT_CST_HIGH (elt_size),
! 				   &lquo, &hquo, &lrem, &hrem)
! 	  || lrem || hrem)
! 	return NULL_TREE;
  
!       idx = build_int_2_wide (lquo, hquo);
!     }
! 
!   /* Assume the low bound is zero.  If there is a domain type, get the
!      low bound, if any, convert the index into that type, and add the
!      low bound.  */
!   min_idx = integer_zero_node;
!   if (TYPE_DOMAIN (array_type))
      {
!       if (TYPE_MIN_VALUE (TYPE_DOMAIN (array_type)))
! 	min_idx = TYPE_MIN_VALUE (TYPE_DOMAIN (array_type));
!       else
! 	min_idx = fold_convert (TYPE_DOMAIN (array_type), min_idx);
! 
!       if (TREE_CODE (min_idx) != INTEGER_CST)
! 	return NULL_TREE;
! 
!       idx = fold_convert (TYPE_DOMAIN (array_type), idx);
!       elt_offset = fold_convert (TYPE_DOMAIN (array_type), elt_offset);
      }
  
!   if (!integer_zerop (min_idx))
!     idx = int_const_binop (PLUS_EXPR, idx, min_idx, 0);
!   if (!integer_zerop (elt_offset))
!     idx = int_const_binop (PLUS_EXPR, idx, elt_offset, 0);
! 
!   return build (ARRAY_REF, orig_type, base, idx, min_idx,
! 		size_int (tree_low_cst (elt_size, 1)
! 			  / (TYPE_ALIGN (elt_type) / BITS_PER_UNIT)));
  }
  
*************** maybe_fold_offset_to_component_ref (tree
*** 1618,1622 ****
  	  if (base_is_ptr)
  	    base = build1 (INDIRECT_REF, record_type, base);
! 	  t = build (COMPONENT_REF, field_type, base, f);
  	  return t;
  	}
--- 1662,1666 ----
  	  if (base_is_ptr)
  	    base = build1 (INDIRECT_REF, record_type, base);
! 	  t = build (COMPONENT_REF, field_type, base, f, NULL_TREE);
  	  return t;
  	}
*************** maybe_fold_offset_to_component_ref (tree
*** 1640,1644 ****
    if (base_is_ptr)
      base = build1 (INDIRECT_REF, record_type, base);
!   base = build (COMPONENT_REF, field_type, base, f);
  
    t = maybe_fold_offset_to_array_ref (base, offset, orig_type);
--- 1684,1688 ----
    if (base_is_ptr)
      base = build1 (INDIRECT_REF, record_type, base);
!   base = build (COMPONENT_REF, field_type, base, f, NULL_TREE);
  
    t = maybe_fold_offset_to_array_ref (base, offset, orig_type);
*************** maybe_fold_stmt_indirect (tree expr, tre
*** 1698,1703 ****
  	return t;
  
!       /* Fold *&B to B.  */
!       if (integer_zerop (offset))
  	return base;
      }
--- 1742,1751 ----
  	return t;
  
!       /* Fold *&B to B.  We can only do this if EXPR is the same type
! 	 as BASE.  We can't do this if EXPR is the element type of an array
! 	 and BASE is the array.  */
!       if (integer_zerop (offset)
! 	  && lang_hooks.types_compatible_p (TREE_TYPE (base),
! 					    TREE_TYPE (expr)))
  	return base;
      }
*************** maybe_fold_stmt_addition (tree expr)
*** 1804,1807 ****
--- 1852,1858 ----
  	  if (min_idx)
  	    {
+ 	      if (TREE_CODE (min_idx) != INTEGER_CST)
+ 		break;
+ 
  	      array_idx = convert (TREE_TYPE (min_idx), array_idx);
  	      if (!integer_zerop (min_idx))
*** tree-ssa-operands.c	17 Jun 2004 18:13:18 -0000	2.9
--- tree-ssa-operands.c	21 Jun 2004 22:50:40 -0000
*************** get_expr_operands (tree stmt, tree *expr
*** 898,917 ****
    class = TREE_CODE_CLASS (code);
  
-   /* Expressions that make no memory references.  */
-   if (class == 'c'
-       || class == 't'
-       || code == BLOCK
-       || code == FUNCTION_DECL
-       || code == EXC_PTR_EXPR
-       || code == FILTER_EXPR
-       || code == LABEL_DECL)
-     return;
- 
    /* We could have the address of a component, array member, etc which
       has interesting variable references.  */
    if (code == ADDR_EXPR)
      {
-       enum tree_code subcode = TREE_CODE (TREE_OPERAND (expr, 0));
- 
        /* Taking the address of a variable does not represent a
  	 reference to it, but the fact that STMT takes its address will be
--- 898,905 ----
*************** get_expr_operands (tree stmt, tree *expr
*** 919,925 ****
        add_stmt_operand (expr_p, stmt, 0, NULL);
  
!       /* If the address is invariant, there may be no interesting variable
! 	 references inside.  */
!       if (is_gimple_min_invariant (expr))
  	return;
  
--- 907,913 ----
        add_stmt_operand (expr_p, stmt, 0, NULL);
  
!       /* If the address is constant (invariant is not sufficient), there will
! 	 be no interesting variable references inside.  */
!       if (TREE_CONSTANT (expr))
  	return;
  
*************** get_expr_operands (tree stmt, tree *expr
*** 931,940 ****
  
        /* Avoid recursion.  */
-       code = subcode;
-       class = TREE_CODE_CLASS (code);
        expr_p = &TREE_OPERAND (expr, 0);
        expr = *expr_p;
      }
  
    /* If we found a variable, add it to DEFS or USES depending on the
       operand flags.  */
--- 919,938 ----
  
        /* Avoid recursion.  */
        expr_p = &TREE_OPERAND (expr, 0);
        expr = *expr_p;
+       code =  TREE_CODE (expr);
+       class = TREE_CODE_CLASS (code);
      }
  
+   /* Expressions that make no memory references.  */
+   if (class == 'c'
+       || class == 't'
+       || code == BLOCK
+       || code == FUNCTION_DECL
+       || code == EXC_PTR_EXPR
+       || code == FILTER_EXPR
+       || code == LABEL_DECL)
+     return;
+ 
    /* If we found a variable, add it to DEFS or USES depending on the
       operand flags.  */
*************** get_expr_operands (tree stmt, tree *expr
*** 1044,1048 ****
       representing the array.  The virtual variable for an ARRAY_REF
       is the VAR_DECL for the array.  */
!   if (code == ARRAY_REF)
      {
        /* Add the virtual variable for the ARRAY_REF to VDEFS or VUSES
--- 1042,1046 ----
       representing the array.  The virtual variable for an ARRAY_REF
       is the VAR_DECL for the array.  */
!   if (code == ARRAY_REF || code == ARRAY_RANGE_REF)
      {
        /* Add the virtual variable for the ARRAY_REF to VDEFS or VUSES
*************** get_expr_operands (tree stmt, tree *expr
*** 1055,1058 ****
--- 1053,1058 ----
  
        get_expr_operands (stmt, &TREE_OPERAND (expr, 1), opf_none, prev_vops);
+       get_expr_operands (stmt, &TREE_OPERAND (expr, 2), opf_none, prev_vops);
+       get_expr_operands (stmt, &TREE_OPERAND (expr, 3), opf_none, prev_vops);
        return;
      }
*************** get_expr_operands (tree stmt, tree *expr
*** 1079,1082 ****
--- 1079,1084 ----
  	get_expr_operands (stmt, &TREE_OPERAND (expr, 0), flags, prev_vops);
  
+       if (code == COMPONENT_REF)
+ 	get_expr_operands (stmt, &TREE_OPERAND (expr, 2), opf_none, prev_vops);
        return;
      }
*** tree-ssa.c	19 Jun 2004 01:52:12 -0000	2.12
--- tree-ssa.c	21 Jun 2004 22:50:40 -0000
*************** set_is_used (tree t)
*** 474,491 ****
  	break;
  
!       switch (TREE_CODE (t))
! 	{
! 	case ARRAY_REF:
! 	case COMPONENT_REF:
! 	case REALPART_EXPR:
! 	case IMAGPART_EXPR:
! 	case BIT_FIELD_REF:
! 	case INDIRECT_REF:
  	  t = TREE_OPERAND (t, 0);
- 	  break;
- 
- 	default:
- 	  return;
- 	}
      }
  
--- 474,482 ----
  	break;
  
!       if (TREE_CODE (t) == REALPART_EXPR || TREE_CODE (t) == IMAGPART_EXPR)
! 	t = TREE_OPERAND (t, 0);
!       else
! 	while (handled_component_p (t))
  	  t = TREE_OPERAND (t, 0);
      }
  
*** tree.c	21 Jun 2004 12:59:58 -0000	1.377
--- tree.c	21 Jun 2004 22:50:43 -0000
*************** substitute_in_expr (tree exp, tree f, tr
*** 1928,1932 ****
         return exp;
  
!      new = fold (build2 (code, TREE_TYPE (exp), op0, TREE_OPERAND (exp, 1)));
     }
    else
--- 1928,1933 ----
         return exp;
  
!      new = fold (build (code, TREE_TYPE (exp), op0, TREE_OPERAND (exp, 1),
! 			NULL_TREE));
     }
    else
*************** stabilize_reference (tree ref)
*** 2158,2162 ****
        result = build_nt (COMPONENT_REF,
  			 stabilize_reference (TREE_OPERAND (ref, 0)),
! 			 TREE_OPERAND (ref, 1));
        break;
  
--- 2159,2163 ----
        result = build_nt (COMPONENT_REF,
  			 stabilize_reference (TREE_OPERAND (ref, 0)),
! 			 TREE_OPERAND (ref, 1), NULL_TREE);
        break;
  
*************** stabilize_reference (tree ref)
*** 2171,2175 ****
        result = build_nt (ARRAY_REF,
  			 stabilize_reference (TREE_OPERAND (ref, 0)),
! 			 stabilize_reference_1 (TREE_OPERAND (ref, 1)));
        break;
  
--- 2172,2177 ----
        result = build_nt (ARRAY_REF,
  			 stabilize_reference (TREE_OPERAND (ref, 0)),
! 			 stabilize_reference_1 (TREE_OPERAND (ref, 1)),
! 			 TREE_OPERAND (ref, 2), TREE_OPERAND (ref, 3));
        break;
  
*************** stabilize_reference (tree ref)
*** 2177,2181 ****
        result = build_nt (ARRAY_RANGE_REF,
  			 stabilize_reference (TREE_OPERAND (ref, 0)),
! 			 stabilize_reference_1 (TREE_OPERAND (ref, 1)));
        break;
  
--- 2179,2184 ----
        result = build_nt (ARRAY_RANGE_REF,
  			 stabilize_reference (TREE_OPERAND (ref, 0)),
! 			 stabilize_reference_1 (TREE_OPERAND (ref, 1)),
! 			 TREE_OPERAND (ref, 2), TREE_OPERAND (ref, 3));
        break;
  
*************** stabilize_reference_1 (tree e)
*** 2293,2331 ****
  /* Low-level constructors for expressions.  */
  
! /* A helper function for build1 and constant folders.
!    Set TREE_CONSTANT and TREE_INVARIANT for an ADDR_EXPR.  */
  
  void
  recompute_tree_invarant_for_addr_expr (tree t)
  {
!   tree node = TREE_OPERAND (t, 0);
!   bool tc = false, ti = false;
  
!   /* Addresses of constants and static variables are constant;
!      all other decl addresses are invariant.  */
!   if (staticp (node))
!     tc = ti = true;
!   else
!     {
!       /* Step past constant offsets.  */
!       while (1)
  	{
! 	  if (TREE_CODE (node) == COMPONENT_REF
! 	      && TREE_CODE (TREE_OPERAND (node, 1)) == FIELD_DECL
! 	      && ! DECL_BIT_FIELD (TREE_OPERAND (node, 1)))
! 	    ;
! 	  else if (TREE_CODE (node) == ARRAY_REF
! 	           && TREE_CONSTANT (TREE_OPERAND (node, 1)))
! 	    ;
! 	  else
! 	    break;
! 	  node = TREE_OPERAND (node, 0);
  	}
!       if (DECL_P (node))
!         ti = true;
      }
  
    TREE_CONSTANT (t) = tc;
    TREE_INVARIANT (t) = ti;
  }
  
--- 2296,2370 ----
  /* Low-level constructors for expressions.  */
  
! /* A helper function for build1 and constant folders.  Set TREE_CONSTANT,
!    TREE_INVARIANT, and TREE_SIDE_EFFECTS for an ADDR_EXPR.  */
  
  void
  recompute_tree_invarant_for_addr_expr (tree t)
  {
!   tree node;
!   bool tc = true, ti = true, se = false;
  
!   /* We started out assuming this address is both invariant and constant, but
!      does not have side effects.  Now go down any handled components and see if
!      any of them involve offsets that are either non-constant or non-invariant.
!      Also check for side-effects.
! 
!      ??? Note that this code makes no attempt to deal with the case where
!      taking the address of something causes a copy due to misalignment.  */
! 
! #define UPDATE_TITCSE(NODE)  \
! do { tree _node = (NODE); \
!      if (_node && !TREE_INVARIANT (_node)) ti = false; \
!      if (_node && !TREE_CONSTANT (_node)) tc = false; \
!      if (_node && TREE_SIDE_EFFECTS (_node)) se = true; } while (0)
! 
!   for (node = TREE_OPERAND (t, 0); handled_component_p (node);
!        node = TREE_OPERAND (node, 0))
!     {
!       /* If the first operand doesn't have an ARRAY_TYPE, this is a bogus
! 	 array reference (probably made temporarily by the G++ front end),
! 	 so ignore all the operands.  */
!       if ((TREE_CODE (node) == ARRAY_REF
! 	   || TREE_CODE (node) == ARRAY_RANGE_REF)
! 	  && TREE_CODE (TREE_TYPE (TREE_OPERAND (node, 0))) == ARRAY_TYPE)
  	{
! 	  UPDATE_TITCSE (TREE_OPERAND (node, 1));
! 	  UPDATE_TITCSE (array_ref_low_bound (node));
! 	  UPDATE_TITCSE (array_ref_element_size (node));
  	}
!       /* Likewise, just because this is a COMPONENT_REF doesn't mean we have a
! 	 FIELD_DECL, apparently.  The G++ front end can put something else
! 	 there, at least temporarily.  */
!       else if (TREE_CODE (node) == COMPONENT_REF
! 	       && TREE_CODE (TREE_OPERAND (node, 1)) == FIELD_DECL)
! 	UPDATE_TITCSE (component_ref_field_offset (node));
!       else if (TREE_CODE (node) == BIT_FIELD_REF)
! 	UPDATE_TITCSE (TREE_OPERAND (node, 2));
!     }
! 	      
!   /* Now see what's inside.  If it's an INDIRECT_REF, copy our properties from
!      it.  If it's a decl, it's definitely invariant and it's constant if the
!      decl is static.  (Taking the address of a volatile variable is not
!      volatile.)  If it's a constant, the address is both invariant and
!      constant.  Otherwise it's neither.  */
!   if (TREE_CODE (node) == INDIRECT_REF)
!     UPDATE_TITCSE (node);
!   else if (DECL_P (node))
!     {
!       if (!staticp (node))
! 	tc = false;
!     }
!   else if (TREE_CODE_CLASS (TREE_CODE (node)) == 'c')
!     ;
!   else
!     {
!       ti = tc = false;
!       se |= TREE_SIDE_EFFECTS (node);
      }
  
    TREE_CONSTANT (t) = tc;
    TREE_INVARIANT (t) = ti;
+   TREE_SIDE_EFFECTS (t) = se;
+ #undef UPDATE_TITCSE
  }
  
*************** build1_stat (enum tree_code code, tree t
*** 2430,2454 ****
      case ADDR_EXPR:
        if (node)
! 	{
! 	  recompute_tree_invarant_for_addr_expr (t);
! 
! 	  /* The address of a volatile decl or reference does not have
! 	     side-effects.  But be careful not to ignore side-effects from
! 	     other sources deeper in the expression--if node is a _REF and
! 	     one of its operands has side-effects, so do we.  */
! 	  if (TREE_THIS_VOLATILE (node))
! 	    {
! 	      TREE_SIDE_EFFECTS (t) = 0;
! 	      if (!DECL_P (node))
! 		{
! 		  int i = first_rtl_op (TREE_CODE (node)) - 1;
! 		  for (; i >= 0; --i)
! 		    {
! 		      if (TREE_SIDE_EFFECTS (TREE_OPERAND (node, i)))
! 			TREE_SIDE_EFFECTS (t) = 1;
! 		    }
! 		}
! 	    }
! 	}
        break;
  
--- 2469,2473 ----
      case ADDR_EXPR:
        if (node)
! 	recompute_tree_invarant_for_addr_expr (t);
        break;
  
*************** build2_stat (enum tree_code code, tree t
*** 2517,2520 ****
--- 2536,2541 ----
    TREE_INVARIANT (t) = invariant;
    TREE_SIDE_EFFECTS (t) = side_effects;  
+   TREE_THIS_VOLATILE (t)
+     = TREE_CODE_CLASS (code) == 'r' && arg0 && TREE_THIS_VOLATILE (arg0);
  
    return t;
*************** build3_stat (enum tree_code code, tree t
*** 2566,2569 ****
--- 2587,2592 ----
  
    TREE_SIDE_EFFECTS (t) = side_effects;  
+   TREE_THIS_VOLATILE (t)
+     = TREE_CODE_CLASS (code) == 'r' && arg0 && TREE_THIS_VOLATILE (arg0);
  
    return t;
*************** build4_stat (enum tree_code code, tree t
*** 2596,2599 ****
--- 2619,2624 ----
  
    TREE_SIDE_EFFECTS (t) = side_effects;  
+   TREE_THIS_VOLATILE (t)
+     = TREE_CODE_CLASS (code) == 'r' && arg0 && TREE_THIS_VOLATILE (arg0);
  
    return t;
*************** get_unwidened (tree op, tree for_type)
*** 4458,4463 ****
  	  && (! uns || final_prec <= innerprec || unsignedp))
  	{
! 	  win = build2 (COMPONENT_REF, type, TREE_OPERAND (op, 0),
! 			TREE_OPERAND (op, 1));
  	  TREE_SIDE_EFFECTS (win) = TREE_SIDE_EFFECTS (op);
  	  TREE_THIS_VOLATILE (win) = TREE_THIS_VOLATILE (op);
--- 4483,4488 ----
  	  && (! uns || final_prec <= innerprec || unsignedp))
  	{
! 	  win = build3 (COMPONENT_REF, type, TREE_OPERAND (op, 0),
! 			TREE_OPERAND (op, 1), NULL_TREE);
  	  TREE_SIDE_EFFECTS (win) = TREE_SIDE_EFFECTS (op);
  	  TREE_THIS_VOLATILE (win) = TREE_THIS_VOLATILE (op);
*************** get_narrower (tree op, int *unsignedp_pt
*** 4524,4528 ****
        && TREE_CODE (TREE_TYPE (op)) != REAL_TYPE
        /* Ensure field is laid out already.  */
!       && DECL_SIZE (TREE_OPERAND (op, 1)) != 0)
      {
        unsigned HOST_WIDE_INT innerprec
--- 4549,4554 ----
        && TREE_CODE (TREE_TYPE (op)) != REAL_TYPE
        /* Ensure field is laid out already.  */
!       && DECL_SIZE (TREE_OPERAND (op, 1)) != 0
!       && host_integerp (DECL_SIZE (TREE_OPERAND (op, 1)), 1))
      {
        unsigned HOST_WIDE_INT innerprec
*************** get_narrower (tree op, int *unsignedp_pt
*** 4547,4552 ****
  	  if (first)
  	    uns = DECL_UNSIGNED (TREE_OPERAND (op, 1));
! 	  win = build2 (COMPONENT_REF, type, TREE_OPERAND (op, 0),
! 			TREE_OPERAND (op, 1));
  	  TREE_SIDE_EFFECTS (win) = TREE_SIDE_EFFECTS (op);
  	  TREE_THIS_VOLATILE (win) = TREE_THIS_VOLATILE (op);
--- 4573,4578 ----
  	  if (first)
  	    uns = DECL_UNSIGNED (TREE_OPERAND (op, 1));
! 	  win = build3 (COMPONENT_REF, type, TREE_OPERAND (op, 0),
! 			TREE_OPERAND (op, 1), NULL_TREE);
  	  TREE_SIDE_EFFECTS (win) = TREE_SIDE_EFFECTS (op);
  	  TREE_THIS_VOLATILE (win) = TREE_THIS_VOLATILE (op);
*** tree.def	18 Jun 2004 02:59:16 -0000	1.80
--- tree.def	21 Jun 2004 22:50:44 -0000
*************** DEFTREECODE (TRANSLATION_UNIT_DECL, "tra
*** 355,361 ****
  
  /* Value is structure or union component.
!    Operand 0 is the structure or union (an expression);
!    operand 1 is the field (a node of type FIELD_DECL).  */
! DEFTREECODE (COMPONENT_REF, "component_ref", 'r', 2)
  
  /* Reference to a group of bits within an object.  Similar to COMPONENT_REF
--- 355,363 ----
  
  /* Value is structure or union component.
!    Operand 0 is the structure or union (an expression).
!    Operand 1 is the field (a node of type FIELD_DECL).
!    Operand 2, if present, is the value of DECL_FIELD_OFFSET, measured
!    in units of DECL_OFFSET_ALIGN / BITS_PER_UNIT.  */
! DEFTREECODE (COMPONENT_REF, "component_ref", 'r', 3)
  
  /* Reference to a group of bits within an object.  Similar to COMPONENT_REF
*************** DEFTREECODE (BUFFER_REF, "buffer_ref", '
*** 375,385 ****
  
  /* Array indexing.
!    Operand 0 is the array; operand 1 is a (single) array index.  */
! DEFTREECODE (ARRAY_REF, "array_ref", 'r', 2)
  
  /* Likewise, except that the result is a range ("slice") of the array.  The
     starting index of the resulting array is taken from operand 1 and the size
     of the range is taken from the type of the expression.  */
! DEFTREECODE (ARRAY_RANGE_REF, "array_range_ref", 'r', 2)
  
  /* Vtable indexing.  Carries data useful for emitting information
--- 377,390 ----
  
  /* Array indexing.
!    Operand 0 is the array; operand 1 is a (single) array index.
!    Operand 2, if present, is a copy of TYPE_MIN_VALUE of the index.
!    Operand 3, if present, is the element size, measured in units of
!    the alignment of the element type.  */
! DEFTREECODE (ARRAY_REF, "array_ref", 'r', 4)
  
  /* Likewise, except that the result is a range ("slice") of the array.  The
     starting index of the resulting array is taken from operand 1 and the size
     of the range is taken from the type of the expression.  */
! DEFTREECODE (ARRAY_RANGE_REF, "array_range_ref", 'r', 4)
  
  /* Vtable indexing.  Carries data useful for emitting information
*** tree.h	20 Jun 2004 17:16:27 -0000	1.524
--- tree.h	21 Jun 2004 22:50:53 -0000
*************** extern tree get_inner_reference (tree, H
*** 3167,3170 ****
--- 3167,3185 ----
  extern int handled_component_p (tree);
  
+ /* Return a tree of sizetype representing the size, in bytes, of the element
+    of EXP, an ARRAY_REF.  */
+ 
+ extern tree array_ref_element_size (tree);
+ 
+ /* Return a tree representing the lower bound of the array mentioned in
+    EXP, an ARRAY_REF.  */
+ 
+ extern tree array_ref_low_bound (tree);
+ 
+ /* Return a tree representing the offset, in bytes, of the field referenced
+    by EXP.  This does not include any offset in DECL_FIELD_BIT_OFFSET.  */
+ 
+ extern tree component_ref_field_offset (tree);
+ 
  /* Given a DECL or TYPE, return the scope in which it was declared, or
     NUL_TREE if there is no containing scope.  */
*** config/alpha/alpha.c	11 Jun 2004 20:21:02 -0000	1.367
--- config/alpha/alpha.c	21 Jun 2004 22:51:03 -0000
*************** alpha_va_start (tree valist, rtx nextarg
*** 6275,6281 ****
  
        base_field = build (COMPONENT_REF, TREE_TYPE (base_field),
! 			  valist, base_field);
        offset_field = build (COMPONENT_REF, TREE_TYPE (offset_field),
! 			    valist, offset_field);
  
        t = make_tree (ptr_type_node, virtual_incoming_args_rtx);
--- 6275,6281 ----
  
        base_field = build (COMPONENT_REF, TREE_TYPE (base_field),
! 			  valist, base_field, NULL_TREE);
        offset_field = build (COMPONENT_REF, TREE_TYPE (offset_field),
! 			    valist, offset_field, NULL_TREE);
  
        t = make_tree (ptr_type_node, virtual_incoming_args_rtx);
*************** alpha_gimplify_va_arg (tree valist, tree
*** 6384,6390 ****
    offset_field = TREE_CHAIN (base_field);
    base_field = build (COMPONENT_REF, TREE_TYPE (base_field),
! 		      valist, base_field);
    offset_field = build (COMPONENT_REF, TREE_TYPE (offset_field),
! 			valist, offset_field);
  
    /* Pull the fields of the structure out into temporaries.  Since we never
--- 6384,6390 ----
    offset_field = TREE_CHAIN (base_field);
    base_field = build (COMPONENT_REF, TREE_TYPE (base_field),
! 		      valist, base_field, NULL_TREE);
    offset_field = build (COMPONENT_REF, TREE_TYPE (offset_field),
! 			valist, offset_field, NULL_TREE);
  
    /* Pull the fields of the structure out into temporaries.  Since we never
*** config/i386/i386.c	21 Jun 2004 20:41:38 -0000	1.677
--- config/i386/i386.c	21 Jun 2004 22:51:16 -0000
*************** ix86_va_start (tree valist, rtx nextarg)
*** 3137,3144 ****
  
    valist = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (valist)), valist);
!   gpr = build (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr);
!   fpr = build (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr);
!   ovf = build (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf);
!   sav = build (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav);
  
    /* Count number of gp and fp argument registers used.  */
--- 3137,3144 ----
  
    valist = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (valist)), valist);
!   gpr = build (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
!   fpr = build (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr, NULL_TREE);
!   ovf = build (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf, NULL_TREE);
!   sav = build (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav, NULL_TREE);
  
    /* Count number of gp and fp argument registers used.  */
*************** ix86_gimplify_va_arg (tree valist, tree 
*** 3203,3210 ****
  
    valist = build_fold_indirect_ref (valist);
!   gpr = build (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr);
!   fpr = build (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr);
!   ovf = build (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf);
!   sav = build (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav);
  
    size = int_size_in_bytes (type);
--- 3203,3210 ----
  
    valist = build_fold_indirect_ref (valist);
!   gpr = build (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
!   fpr = build (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr, NULL_TREE);
!   ovf = build (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf, NULL_TREE);
!   sav = build (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav, NULL_TREE);
  
    size = int_size_in_bytes (type);
*** config/i860/i860.c	11 Mar 2004 05:54:31 -0000	1.43
--- config/i860/i860.c	21 Jun 2004 22:51:20 -0000
*************** i860_va_start (tree valist, rtx nextarg 
*** 1878,1885 ****
  #endif
  
!   gpr = build (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr);
!   fpr = build (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr);
!   sav = build (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav);
!   mem = build (COMPONENT_REF, TREE_TYPE (f_mem), valist, f_mem);
  
    /* Initialize the `mem_ptr' field to the address of the first anonymous
--- 1878,1885 ----
  #endif
  
!   gpr = build (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
!   fpr = build (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr, NULL_TREE);
!   sav = build (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav, NULL_TREE);
!   mem = build (COMPONENT_REF, TREE_TYPE (f_mem), valist, f_mem, NULL_TREE);
  
    /* Initialize the `mem_ptr' field to the address of the first anonymous
*************** i860_va_arg (tree valist, tree type)
*** 1944,1951 ****
  #endif
  
!   gpr = build (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr);
!   fpr = build (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr);
!   mem = build (COMPONENT_REF, TREE_TYPE (f_mem), valist, f_mem);
!   sav = build (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav);
  
    size = int_size_in_bytes (type);
--- 1944,1951 ----
  #endif
  
!   gpr = build (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
!   fpr = build (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr, NULL_TREE);
!   mem = build (COMPONENT_REF, TREE_TYPE (f_mem), valist, f_mem, NULL_TREE);
!   sav = build (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav, NULL_TREE);
  
    size = int_size_in_bytes (type);
*** config/iq2000/iq2000.c	1 Apr 2004 03:50:33 -0000	1.17
--- config/iq2000/iq2000.c	21 Jun 2004 22:51:31 -0000
*************** iq2000_va_arg (tree valist, tree type)
*** 1657,1665 ****
    f_foff = TREE_CHAIN (f_goff);
  
!   ovfl = build (COMPONENT_REF, TREE_TYPE (f_ovfl), valist, f_ovfl);
!   gtop = build (COMPONENT_REF, TREE_TYPE (f_gtop), valist, f_gtop);
!   ftop = build (COMPONENT_REF, TREE_TYPE (f_ftop), valist, f_ftop);
!   goff = build (COMPONENT_REF, TREE_TYPE (f_goff), valist, f_goff);
!   foff = build (COMPONENT_REF, TREE_TYPE (f_foff), valist, f_foff);
  
    lab_false = gen_label_rtx ();
--- 1657,1665 ----
    f_foff = TREE_CHAIN (f_goff);
  
!   ovfl = build (COMPONENT_REF, TREE_TYPE (f_ovfl), valist, f_ovfl, NULL_TREE);
!   gtop = build (COMPONENT_REF, TREE_TYPE (f_gtop), valist, f_gtop, NULL_TREE);
!   ftop = build (COMPONENT_REF, TREE_TYPE (f_ftop), valist, f_ftop, NULL_TREE);
!   goff = build (COMPONENT_REF, TREE_TYPE (f_goff), valist, f_goff, NULL_TREE);
!   foff = build (COMPONENT_REF, TREE_TYPE (f_foff), valist, f_foff, NULL_TREE);
  
    lab_false = gen_label_rtx ();
*** config/mips/mips.c	4 Jun 2004 00:37:56 -0000	1.417
--- config/mips/mips.c	21 Jun 2004 22:51:43 -0000
*************** mips_va_start (tree valist, rtx nextarg)
*** 4046,4054 ****
  	  f_foff = TREE_CHAIN (f_goff);
  
! 	  ovfl = build (COMPONENT_REF, TREE_TYPE (f_ovfl), valist, f_ovfl);
! 	  gtop = build (COMPONENT_REF, TREE_TYPE (f_gtop), valist, f_gtop);
! 	  ftop = build (COMPONENT_REF, TREE_TYPE (f_ftop), valist, f_ftop);
! 	  goff = build (COMPONENT_REF, TREE_TYPE (f_goff), valist, f_goff);
! 	  foff = build (COMPONENT_REF, TREE_TYPE (f_foff), valist, f_foff);
  
  	  /* Emit code to initialize OVFL, which points to the next varargs
--- 4046,4059 ----
  	  f_foff = TREE_CHAIN (f_goff);
  
! 	  ovfl = build (COMPONENT_REF, TREE_TYPE (f_ovfl), valist, f_ovfl,
! 			NULL_TREE);
! 	  gtop = build (COMPONENT_REF, TREE_TYPE (f_gtop), valist, f_gtop,
! 			NULL_TREE);
! 	  ftop = build (COMPONENT_REF, TREE_TYPE (f_ftop), valist, f_ftop,
! 			NULL_TREE);
! 	  goff = build (COMPONENT_REF, TREE_TYPE (f_goff), valist, f_goff,
! 			NULL_TREE);
! 	  foff = build (COMPONENT_REF, TREE_TYPE (f_foff), valist, f_foff,
! 			NULL_TREE);
  
  	  /* Emit code to initialize OVFL, which points to the next varargs
*************** mips_va_arg (tree valist, tree type)
*** 4213,4222 ****
  	  lab_over = gen_label_rtx ();
  
! 	  ovfl = build (COMPONENT_REF, TREE_TYPE (f_ovfl), valist, f_ovfl);
  	  if (GET_MODE_CLASS (TYPE_MODE (type)) == MODE_FLOAT
  	      && GET_MODE_SIZE (TYPE_MODE (type)) <= UNITS_PER_FPVALUE)
  	    {
! 	      top = build (COMPONENT_REF, TREE_TYPE (f_ftop), valist, f_ftop);
! 	      off = build (COMPONENT_REF, TREE_TYPE (f_foff), valist, f_foff);
  
  	      /* When floating-point registers are saved to the stack,
--- 4218,4230 ----
  	  lab_over = gen_label_rtx ();
  
! 	  ovfl = build (COMPONENT_REF, TREE_TYPE (f_ovfl), valist, f_ovfl,
! 			NULL_TREE);
  	  if (GET_MODE_CLASS (TYPE_MODE (type)) == MODE_FLOAT
  	      && GET_MODE_SIZE (TYPE_MODE (type)) <= UNITS_PER_FPVALUE)
  	    {
! 	      top = build (COMPONENT_REF, TREE_TYPE (f_ftop), valist, f_ftop,
! 			   NULL_TREE);
! 	      off = build (COMPONENT_REF, TREE_TYPE (f_foff), valist, f_foff,
! 			   NULL_TREE);
  
  	      /* When floating-point registers are saved to the stack,
*************** mips_va_arg (tree valist, tree type)
*** 4246,4251 ****
  	  else
  	    {
! 	      top = build (COMPONENT_REF, TREE_TYPE (f_gtop), valist, f_gtop);
! 	      off = build (COMPONENT_REF, TREE_TYPE (f_goff), valist, f_goff);
  	      if (rsize > UNITS_PER_WORD)
  		{
--- 4254,4261 ----
  	  else
  	    {
! 	      top = build (COMPONENT_REF, TREE_TYPE (f_gtop), valist, f_gtop,
! 			   NULL_TREE);
! 	      off = build (COMPONENT_REF, TREE_TYPE (f_goff), valist, f_goff,
! 			   NULL_TREE);
  	      if (rsize > UNITS_PER_WORD)
  		{
*** config/rs6000/rs6000.c	11 Jun 2004 18:41:44 -0000	1.650
--- config/rs6000/rs6000.c	21 Jun 2004 22:51:51 -0000
*************** rs6000_va_start (tree valist, rtx nextar
*** 5027,5034 ****
  
    valist = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (valist)), valist);
!   gpr = build (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr);
!   fpr = build (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr);
!   ovf = build (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf);
!   sav = build (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav);
  
    /* Count number of gp and fp argument registers used.  */
--- 5027,5034 ----
  
    valist = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (valist)), valist);
!   gpr = build (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
!   fpr = build (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr, NULL_TREE);
!   ovf = build (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf, NULL_TREE);
!   sav = build (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav, NULL_TREE);
  
    /* Count number of gp and fp argument registers used.  */
*************** rs6000_gimplify_va_arg (tree valist, tre
*** 5132,5139 ****
  
    valist = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (valist)), valist);
!   gpr = build (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr);
!   fpr = build (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr);
!   ovf = build (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf);
!   sav = build (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav);
  
    size = int_size_in_bytes (type);
--- 5132,5139 ----
  
    valist = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (valist)), valist);
!   gpr = build (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
!   fpr = build (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr, NULL_TREE);
!   ovf = build (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf, NULL_TREE);
!   sav = build (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav, NULL_TREE);
  
    size = int_size_in_bytes (type);
*** config/s390/s390.c	18 Jun 2004 14:27:24 -0000	1.151
--- config/s390/s390.c	21 Jun 2004 22:51:56 -0000
*************** s390_va_start (tree valist, rtx nextarg 
*** 6382,6389 ****
  
    valist = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (valist)), valist);
!   gpr = build (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr);
!   fpr = build (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr);
!   ovf = build (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf);
!   sav = build (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav);
  
    /* Count number of gp and fp argument registers used.  */
--- 6382,6389 ----
  
    valist = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (valist)), valist);
!   gpr = build (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
!   fpr = build (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr, NULL_TREE);
!   ovf = build (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf, NULL_TREE);
!   sav = build (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav, NULL_TREE);
  
    /* Count number of gp and fp argument registers used.  */
*************** s390_gimplify_va_arg (tree valist, tree 
*** 6463,6470 ****
  
    valist = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (valist)), valist);
!   gpr = build (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr);
!   fpr = build (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr);
!   ovf = build (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf);
!   sav = build (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav);
  
    size = int_size_in_bytes (type);
--- 6463,6470 ----
  
    valist = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (valist)), valist);
!   gpr = build (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
!   fpr = build (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr, NULL_TREE);
!   ovf = build (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf, NULL_TREE);
!   sav = build (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav, NULL_TREE);
  
    size = int_size_in_bytes (type);
*** config/sh/sh.c	10 Jun 2004 18:14:52 -0000	1.271
--- config/sh/sh.c	21 Jun 2004 22:52:01 -0000
*************** sh_va_start (tree valist, rtx nextarg)
*** 6238,6249 ****
    f_next_stack = TREE_CHAIN (f_next_fp_limit);
  
!   next_o = build (COMPONENT_REF, TREE_TYPE (f_next_o), valist, f_next_o);
    next_o_limit = build (COMPONENT_REF, TREE_TYPE (f_next_o_limit),
! 			valist, f_next_o_limit);
!   next_fp = build (COMPONENT_REF, TREE_TYPE (f_next_fp), valist, f_next_fp);
    next_fp_limit = build (COMPONENT_REF, TREE_TYPE (f_next_fp_limit),
! 			 valist, f_next_fp_limit);
    next_stack = build (COMPONENT_REF, TREE_TYPE (f_next_stack),
! 		      valist, f_next_stack);
  
    /* Call __builtin_saveregs.  */
--- 6238,6251 ----
    f_next_stack = TREE_CHAIN (f_next_fp_limit);
  
!   next_o = build (COMPONENT_REF, TREE_TYPE (f_next_o), valist, f_next_o,
! 		  NULL_TREE);
    next_o_limit = build (COMPONENT_REF, TREE_TYPE (f_next_o_limit),
! 			valist, f_next_o_limit, NULL_TREE);
!   next_fp = build (COMPONENT_REF, TREE_TYPE (f_next_fp), valist, f_next_fp,
! 		   NULL_TREE);
    next_fp_limit = build (COMPONENT_REF, TREE_TYPE (f_next_fp_limit),
! 			 valist, f_next_fp_limit, NULL_TREE);
    next_stack = build (COMPONENT_REF, TREE_TYPE (f_next_stack),
! 		      valist, f_next_stack, NULL_TREE);
  
    /* Call __builtin_saveregs.  */
*************** sh_va_arg (tree valist, tree type)
*** 6318,6330 ****
        f_next_stack = TREE_CHAIN (f_next_fp_limit);
  
!       next_o = build (COMPONENT_REF, TREE_TYPE (f_next_o), valist, f_next_o);
        next_o_limit = build (COMPONENT_REF, TREE_TYPE (f_next_o_limit),
! 			    valist, f_next_o_limit);
        next_fp = build (COMPONENT_REF, TREE_TYPE (f_next_fp),
! 		       valist, f_next_fp);
        next_fp_limit = build (COMPONENT_REF, TREE_TYPE (f_next_fp_limit),
! 			     valist, f_next_fp_limit);
        next_stack = build (COMPONENT_REF, TREE_TYPE (f_next_stack),
! 			  valist, f_next_stack);
  
        /* Structures with a single member with a distinct mode are passed
--- 6320,6333 ----
        f_next_stack = TREE_CHAIN (f_next_fp_limit);
  
!       next_o = build (COMPONENT_REF, TREE_TYPE (f_next_o), valist, f_next_o,
! 		      NULL_TREE);
        next_o_limit = build (COMPONENT_REF, TREE_TYPE (f_next_o_limit),
! 			    valist, f_next_o_limit, NULL_TREE);
        next_fp = build (COMPONENT_REF, TREE_TYPE (f_next_fp),
! 		       valist, f_next_fp, NULL_TREE);
        next_fp_limit = build (COMPONENT_REF, TREE_TYPE (f_next_fp_limit),
! 			     valist, f_next_fp_limit, NULL_TREE);
        next_stack = build (COMPONENT_REF, TREE_TYPE (f_next_stack),
! 			  valist, f_next_stack, NULL_TREE);
  
        /* Structures with a single member with a distinct mode are passed
*** config/stormy16/stormy16.c	11 Mar 2004 05:54:35 -0000	1.60
--- config/stormy16/stormy16.c	21 Jun 2004 22:52:04 -0000
*************** xstormy16_expand_builtin_va_start (tree 
*** 1286,1291 ****
    f_count = TREE_CHAIN (f_base);
    
!   base = build (COMPONENT_REF, TREE_TYPE (f_base), valist, f_base);
!   count = build (COMPONENT_REF, TREE_TYPE (f_count), valist, f_count);
  
    t = make_tree (TREE_TYPE (base), virtual_incoming_args_rtx);
--- 1286,1292 ----
    f_count = TREE_CHAIN (f_base);
    
!   base = build (COMPONENT_REF, TREE_TYPE (f_base), valist, f_base, NULL_TREE);
!   count = build (COMPONENT_REF, TREE_TYPE (f_count), valist, f_count,
! 		 NULL_TREE);
  
    t = make_tree (TREE_TYPE (base), virtual_incoming_args_rtx);
*************** xstormy16_expand_builtin_va_arg (tree va
*** 1321,1326 ****
    f_count = TREE_CHAIN (f_base);
    
!   base = build (COMPONENT_REF, TREE_TYPE (f_base), valist, f_base);
!   count = build (COMPONENT_REF, TREE_TYPE (f_count), valist, f_count);
  
    must_stack = MUST_PASS_IN_STACK (TYPE_MODE (type), type);
--- 1322,1328 ----
    f_count = TREE_CHAIN (f_base);
    
!   base = build (COMPONENT_REF, TREE_TYPE (f_base), valist, f_base, NULL_TREE);
!   count = build (COMPONENT_REF, TREE_TYPE (f_count), valist, f_count,
! 		 NULL_TREE);
  
    must_stack = MUST_PASS_IN_STACK (TYPE_MODE (type), type);
*** config/xtensa/xtensa.c	18 Jun 2004 19:38:26 -0000	1.58
--- config/xtensa/xtensa.c	21 Jun 2004 22:52:06 -0000
*************** xtensa_va_start (tree valist, rtx nextar
*** 2431,2437 ****
    f_ndx = TREE_CHAIN (f_reg);
  
!   stk = build (COMPONENT_REF, TREE_TYPE (f_stk), valist, f_stk);
!   reg = build (COMPONENT_REF, TREE_TYPE (f_reg), valist, f_reg);
!   ndx = build (COMPONENT_REF, TREE_TYPE (f_ndx), valist, f_ndx);
  
    /* Call __builtin_saveregs; save the result in __va_reg */
--- 2431,2437 ----
    f_ndx = TREE_CHAIN (f_reg);
  
!   stk = build (COMPONENT_REF, TREE_TYPE (f_stk), valist, f_stk, NULL_TREE);
!   reg = build (COMPONENT_REF, TREE_TYPE (f_reg), valist, f_reg, NULL_TREE);
!   ndx = build (COMPONENT_REF, TREE_TYPE (f_ndx), valist, f_ndx, NULL_TREE);
  
    /* Call __builtin_saveregs; save the result in __va_reg */
*************** xtensa_va_arg (tree valist, tree type)
*** 2495,2501 ****
    f_ndx = TREE_CHAIN (f_reg);
  
!   stk = build (COMPONENT_REF, TREE_TYPE (f_stk), valist, f_stk);
!   reg = build (COMPONENT_REF, TREE_TYPE (f_reg), valist, f_reg);
!   ndx = build (COMPONENT_REF, TREE_TYPE (f_ndx), valist, f_ndx);
  
    type_size = TYPE_SIZE_UNIT (TYPE_MAIN_VARIANT (type));
--- 2495,2501 ----
    f_ndx = TREE_CHAIN (f_reg);
  
!   stk = build (COMPONENT_REF, TREE_TYPE (f_stk), valist, f_stk, NULL_TREE);
!   reg = build (COMPONENT_REF, TREE_TYPE (f_reg), valist, f_reg, NULL_TREE);
!   ndx = build (COMPONENT_REF, TREE_TYPE (f_ndx), valist, f_ndx, NULL_TREE);
  
    type_size = TYPE_SIZE_UNIT (TYPE_MAIN_VARIANT (type));
*** cp/call.c	16 Jun 2004 01:21:29 -0000	1.481
--- cp/call.c	21 Jun 2004 22:52:10 -0000
*************** build_vfield_ref (tree datum, tree type)
*** 204,208 ****
  
    return build (COMPONENT_REF, TREE_TYPE (TYPE_VFIELD (type)),
! 		datum, TYPE_VFIELD (type));
  }
  
--- 204,208 ----
  
    return build (COMPONENT_REF, TREE_TYPE (TYPE_VFIELD (type)),
! 		datum, TYPE_VFIELD (type), NULL_TREE);
  }
  
*************** build_new_method_call (tree instance, tr
*** 5361,5365 ****
      call = (build_min_non_dep
  	    (CALL_EXPR, call,
! 	     build_min_nt (COMPONENT_REF, orig_instance, orig_fns),
  	     orig_args, NULL_TREE));
  
--- 5360,5364 ----
      call = (build_min_non_dep
  	    (CALL_EXPR, call,
! 	     build_min_nt (COMPONENT_REF, orig_instance, orig_fns, NULL_TREE),
  	     orig_args, NULL_TREE));
  
*** cp/decl.c	20 Jun 2004 09:18:10 -0000	1.1222
--- cp/decl.c	21 Jun 2004 22:52:15 -0000
*************** nonstatic_local_decl_p (tree t)
*** 8509,8520 ****
  
  static tree
! local_variable_p_walkfn (tree* tp,
!                          int* walk_subtrees ATTRIBUTE_UNUSED ,
!                          void* data ATTRIBUTE_UNUSED )
  {
!   return ((local_variable_p (*tp) && !DECL_ARTIFICIAL (*tp))
! 	  ? *tp : NULL_TREE);
  }
  
  /* Check that ARG, which is a default-argument expression for a
     parameter DECL, is valid.  Returns ARG, or ERROR_MARK_NODE, if
--- 8509,8524 ----
  
  static tree
! local_variable_p_walkfn (tree *tp, int *walk_subtrees,
! 			 void *data ATTRIBUTE_UNUSED)
  {
!   if (local_variable_p (*tp) && !DECL_ARTIFICIAL (*tp))
!     return *tp;
!   else if (TYPE_P (*tp))
!     *walk_subtrees = 0;
! 
!   return NULL_TREE;
  }
  
+ 
  /* Check that ARG, which is a default-argument expression for a
     parameter DECL, is valid.  Returns ARG, or ERROR_MARK_NODE, if
*** cp/decl2.c	17 Jun 2004 21:11:38 -0000	1.716
--- cp/decl2.c	21 Jun 2004 22:52:17 -0000
*************** grok_array_decl (tree array_expr, tree i
*** 370,374 ****
        if (type_dependent_expression_p (array_expr)
  	  || type_dependent_expression_p (index_exp))
! 	return build_min_nt (ARRAY_REF, array_expr, index_exp);
        array_expr = build_non_dependent_expr (array_expr);
        index_exp = build_non_dependent_expr (index_exp);
--- 370,375 ----
        if (type_dependent_expression_p (array_expr)
  	  || type_dependent_expression_p (index_exp))
! 	return build_min_nt (ARRAY_REF, array_expr, index_exp,
! 			     NULL_TREE, NULL_TREE);
        array_expr = build_non_dependent_expr (array_expr);
        index_exp = build_non_dependent_expr (index_exp);
*************** grok_array_decl (tree array_expr, tree i
*** 427,432 ****
      }
    if (processing_template_decl && expr != error_mark_node)
!     return build_min_non_dep (ARRAY_REF, expr,
! 			      orig_array_expr, orig_index_exp);
    return expr;
  }
--- 428,433 ----
      }
    if (processing_template_decl && expr != error_mark_node)
!     return build_min_non_dep (ARRAY_REF, expr, orig_array_expr, orig_index_exp,
! 			      NULL_TREE, NULL_TREE);
    return expr;
  }
*************** build_anon_union_vars (tree object)
*** 1176,1180 ****
  
        if (processing_template_decl)
! 	ref = build_min_nt (COMPONENT_REF, object, DECL_NAME (field));
        else
  	ref = build_class_member_access_expr (object, field, NULL_TREE,
--- 1177,1182 ----
  
        if (processing_template_decl)
! 	ref = build_min_nt (COMPONENT_REF, object,
! 			    DECL_NAME (field), NULL_TREE);
        else
  	ref = build_class_member_access_expr (object, field, NULL_TREE,
*** cp/init.c	16 Jun 2004 01:21:30 -0000	1.374
--- cp/init.c	21 Jun 2004 22:52:18 -0000
*************** build_new (tree placement, tree decl, tr
*** 1778,1782 ****
        if (has_array)
  	t = tree_cons (tree_cons (NULL_TREE, type, NULL_TREE),
! 		       build_min_nt (ARRAY_REF, NULL_TREE, nelts),
  		       NULL_TREE);
        else
--- 1778,1783 ----
        if (has_array)
  	t = tree_cons (tree_cons (NULL_TREE, type, NULL_TREE),
! 		       build_min_nt (ARRAY_REF, NULL_TREE, nelts,
! 				     NULL_TREE, NULL_TREE),
  		       NULL_TREE);
        else
*************** build_new (tree placement, tree decl, tr
*** 1816,1820 ****
  
    if (has_array)
!     t = build_nt (ARRAY_REF, type, nelts);
    else
      t = type;
--- 1817,1821 ----
  
    if (has_array)
!     t = build_nt (ARRAY_REF, type, nelts, NULL_TREE, NULL_TREE);
    else
      t = type;
*** cp/method.c	20 Jun 2004 08:34:50 -0000	1.286
--- cp/method.c	21 Jun 2004 22:52:25 -0000
*************** do_build_copy_constructor (tree fndecl)
*** 592,596 ****
  	  if (TREE_CODE (expr_type) != REFERENCE_TYPE)
  	    expr_type = cp_build_qualified_type (expr_type, cvquals);
! 	  init = build (COMPONENT_REF, expr_type, init, field);
  	  init = build_tree_list (NULL_TREE, init);
  
--- 592,596 ----
  	  if (TREE_CODE (expr_type) != REFERENCE_TYPE)
  	    expr_type = cp_build_qualified_type (expr_type, cvquals);
! 	  init = build (COMPONENT_REF, expr_type, init, field, NULL_TREE);
  	  init = build_tree_list (NULL_TREE, init);
  
*************** do_build_assign_ref (tree fndecl)
*** 688,695 ****
  	    continue;
  
! 	  comp = build (COMPONENT_REF, TREE_TYPE (field), comp, field);
  	  init = build (COMPONENT_REF,
  	                cp_build_qualified_type (TREE_TYPE (field), cvquals),
! 	                init, field);
  
  	  if (DECL_NAME (field))
--- 688,696 ----
  	    continue;
  
! 	  comp = build (COMPONENT_REF, TREE_TYPE (field), comp, field,
! 			NULL_TREE);
  	  init = build (COMPONENT_REF,
  	                cp_build_qualified_type (TREE_TYPE (field), cvquals),
! 	                init, field, NULL_TREE);
  
  	  if (DECL_NAME (field))
*** cp/parser.c	17 Jun 2004 01:24:04 -0000	1.211
--- cp/parser.c	21 Jun 2004 22:52:33 -0000
*************** cp_parser_direct_new_declarator (cp_pars
*** 4768,4772 ****
  
        /* Add this bound to the declarator.  */
!       declarator = build_nt (ARRAY_REF, declarator, expression);
  
        /* If the next token is not a `[', then there are no more
--- 4768,4773 ----
  
        /* Add this bound to the declarator.  */
!       declarator = build_nt (ARRAY_REF, declarator, expression,
! 			     NULL_TREE, NULL_TREE);
  
        /* If the next token is not a `[', then there are no more
*************** cp_parser_direct_declarator (cp_parser* 
*** 10715,10719 ****
  	    }
  
! 	  declarator = build_nt (ARRAY_REF, declarator, bounds);
  	}
        else if (first && dcl_kind != CP_PARSER_DECLARATOR_ABSTRACT)
--- 10716,10721 ----
  	    }
  
! 	  declarator = build_nt (ARRAY_REF, declarator, bounds,
! 				 NULL_TREE, NULL_TREE);
  	}
        else if (first && dcl_kind != CP_PARSER_DECLARATOR_ABSTRACT)
*** cp/pt.c	20 Jun 2004 10:10:01 -0000	1.870
--- cp/pt.c	21 Jun 2004 22:52:40 -0000
*************** tsubst (tree t, tree args, tsubst_flags_
*** 7202,7206 ****
  	  return error_mark_node;
  
! 	return build_nt (ARRAY_REF, e1, e2);
        }
  
--- 7202,7206 ----
  	  return error_mark_node;
  
! 	return build_nt (ARRAY_REF, e1, e2, NULL_TREE, NULL_TREE);
        }
  
*************** tsubst_copy (tree t, tree args, tsubst_f
*** 7564,7568 ****
  	else
  	  name = tsubst_copy (name, args, complain, in_decl);
! 	return build_nt (COMPONENT_REF, object, name);
        }
  
--- 7564,7568 ----
  	else
  	  name = tsubst_copy (name, args, complain, in_decl);
! 	return build_nt (COMPONENT_REF, object, name, NULL_TREE);
        }
  
*************** tsubst_copy_and_build (tree t, 
*** 8144,8148 ****
  	if (object)
  	  return build (COMPONENT_REF, TREE_TYPE (template), 
! 			object, template);
  	else
  	  return template;
--- 8144,8148 ----
  	if (object)
  	  return build (COMPONENT_REF, TREE_TYPE (template), 
! 			object, template, NULL_TREE);
  	else
  	  return template;
*************** tsubst_copy_and_build (tree t, 
*** 8256,8260 ****
  	  == NULL_TREE)
  	/* new-type-id */
! 	return build_nt (ARRAY_REF, NULL_TREE, RECUR (TREE_OPERAND (t, 1)));
  
        op1 = tsubst_non_call_postfix_expression (TREE_OPERAND (t, 0),
--- 8256,8261 ----
  	  == NULL_TREE)
  	/* new-type-id */
! 	return build_nt (ARRAY_REF, NULL_TREE, RECUR (TREE_OPERAND (t, 1)),
! 			 NULL_TREE, NULL_TREE);
  
        op1 = tsubst_non_call_postfix_expression (TREE_OPERAND (t, 0),
*** cp/semantics.c	21 Jun 2004 09:15:25 -0000	1.406
--- cp/semantics.c	21 Jun 2004 22:52:41 -0000
*************** finish_non_static_data_member (tree decl
*** 1234,1238 ****
  	}
        
!       return build_min (COMPONENT_REF, type, object, decl);
      }
    else
--- 1234,1238 ----
  	}
        
!       return build_min (COMPONENT_REF, type, object, decl, NULL_TREE);
      }
    else
*** cp/tree.c	19 Jun 2004 19:34:23 -0000	1.380
--- cp/tree.c	21 Jun 2004 22:52:43 -0000
*************** bind_template_template_parm (tree t, tre
*** 1027,1035 ****
  
  static tree
! count_trees_r (tree* tp ATTRIBUTE_UNUSED , 
!                int* walk_subtrees ATTRIBUTE_UNUSED , 
!                void* data)
  {
!   ++ *((int*) data);
    return NULL_TREE;
  }
--- 1027,1037 ----
  
  static tree
! count_trees_r (tree *tp, int *walk_subtrees, void *data)
  {
!   ++*((int *) data);
! 
!   if (TYPE_P (*tp))
!     *walk_subtrees = 0;
! 
    return NULL_TREE;
  }
*************** find_tree (tree t, tree x)
*** 1108,1114 ****
  
  static tree
! no_linkage_helper (tree* tp, 
!                    int* walk_subtrees ATTRIBUTE_UNUSED , 
!                    void* data ATTRIBUTE_UNUSED )
  {
    tree t = *tp;
--- 1110,1115 ----
  
  static tree
! no_linkage_helper (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
! 		   void *data ATTRIBUTE_UNUSED)
  {
    tree t = *tp;
*************** no_linkage_helper (tree* tp, 
*** 1119,1122 ****
--- 1120,1124 ----
  	  || TYPE_ANONYMOUS_P (t)))
      return t;
+ 
    return NULL_TREE;
  }
*** cp/typeck.c	20 Jun 2004 08:34:50 -0000	1.550
--- cp/typeck.c	21 Jun 2004 22:52:45 -0000
*************** build_class_member_access_expr (tree obj
*** 1757,1761 ****
  	}
  
!       result = fold (build (COMPONENT_REF, member_type, object, member));
  
        /* Mark the expression const or volatile, as appropriate.  Even
--- 1757,1762 ----
  	}
  
!       result = fold (build (COMPONENT_REF, member_type, object, member,
! 			    NULL_TREE));
  
        /* Mark the expression const or volatile, as appropriate.  Even
*************** build_class_member_access_expr (tree obj
*** 1784,1788 ****
        /* Note that we do not convert OBJECT to the BASELINK_BINFO
  	 base.  That will happen when the function is called.  */
!       result = build (COMPONENT_REF, type, object, member);
      }
    else if (TREE_CODE (member) == CONST_DECL)
--- 1785,1789 ----
        /* Note that we do not convert OBJECT to the BASELINK_BINFO
  	 base.  That will happen when the function is called.  */
!       result = build (COMPONENT_REF, type, object, member, NULL_TREE);
      }
    else if (TREE_CODE (member) == CONST_DECL)
*************** finish_class_member_access_expr (tree ob
*** 1883,1887 ****
  	      && TYPE_P (TREE_OPERAND (name, 0))
  	      && dependent_type_p (TREE_OPERAND (name, 0))))
! 	return build_min_nt (COMPONENT_REF, object, name);
        object = build_non_dependent_expr (object);
      }
--- 1884,1888 ----
  	      && TYPE_P (TREE_OPERAND (name, 0))
  	      && dependent_type_p (TREE_OPERAND (name, 0))))
! 	return build_min_nt (COMPONENT_REF, object, name, NULL_TREE);
        object = build_non_dependent_expr (object);
      }
*************** finish_class_member_access_expr (tree ob
*** 2010,2014 ****
    if (processing_template_decl && expr != error_mark_node)
      return build_min_non_dep (COMPONENT_REF, expr,
! 			      orig_object, orig_name);
    return expr;
  }
--- 2011,2015 ----
    if (processing_template_decl && expr != error_mark_node)
      return build_min_non_dep (COMPONENT_REF, expr,
! 			      orig_object, orig_name, NULL_TREE);
    return expr;
  }
*************** build_ptrmemfunc_access_expr (tree ptrme
*** 2038,2042 ****
    member_type = cp_build_qualified_type (TREE_TYPE (member),
  					 cp_type_quals (ptrmem_type));
!   return fold (build (COMPONENT_REF, member_type, ptrmem, member));
  }
  
--- 2039,2043 ----
    member_type = cp_build_qualified_type (TREE_TYPE (member),
  					 cp_type_quals (ptrmem_type));
!   return fold (build (COMPONENT_REF, member_type, ptrmem, member, NULL_TREE));
  }
  
*************** build_array_ref (tree array, tree idx)
*** 2254,2258 ****
  
        type = TREE_TYPE (TREE_TYPE (array));
!       rval = build (ARRAY_REF, type, array, idx);
        /* Array ref is const/volatile if the array elements are
  	 or if the array is..  */
--- 2255,2259 ----
  
        type = TREE_TYPE (TREE_TYPE (array));
!       rval = build (ARRAY_REF, type, array, idx, NULL_TREE, NULL_TREE);
        /* Array ref is const/volatile if the array elements are
  	 or if the array is..  */
diff -c -2 -p -r1.160 typeck2.c
*** cp/typeck2.c	16 Jun 2004 01:21:35 -0000	1.160
--- cp/typeck2.c	21 Jun 2004 22:52:49 -0000
*************** split_nonconstant_init_1 (tree dest, tre
*** 325,331 ****
  	    {
  	      if (array_type_p)
! 	        sub = build (ARRAY_REF, inner_type, dest, field_index);
  	      else
! 	        sub = build (COMPONENT_REF, inner_type, dest, field_index);
  
  	      split_nonconstant_init_1 (sub, value);
--- 325,333 ----
  	    {
  	      if (array_type_p)
! 	        sub = build (ARRAY_REF, inner_type, dest, field_index,
! 			     NULL_TREE, NULL_TREE);
  	      else
! 	        sub = build (COMPONENT_REF, inner_type, dest, field_index,
! 			     NULL_TREE);
  
  	      split_nonconstant_init_1 (sub, value);
*************** split_nonconstant_init_1 (tree dest, tre
*** 336,342 ****
  
  	      if (array_type_p)
! 	        sub = build (ARRAY_REF, inner_type, dest, field_index);
  	      else
! 	        sub = build (COMPONENT_REF, inner_type, dest, field_index);
  
  	      code = build (MODIFY_EXPR, inner_type, sub, value);
--- 338,346 ----
  
  	      if (array_type_p)
! 	        sub = build (ARRAY_REF, inner_type, dest, field_index,
! 			     NULL_TREE, NULL_TREE);
  	      else
! 	        sub = build (COMPONENT_REF, inner_type, dest, field_index,
! 			     NULL_TREE);
  
  	      code = build (MODIFY_EXPR, inner_type, sub, value);
*** fortran/f95-lang.c	19 May 2004 00:34:55 -0000	1.5
--- fortran/f95-lang.c	21 Jun 2004 22:53:03 -0000
*************** static void gfc_expand_function (tree);
*** 123,127 ****
  #undef LANG_HOOKS_SIGNED_TYPE
  #undef LANG_HOOKS_SIGNED_OR_UNSIGNED_TYPE
- #undef LANG_HOOKS_GIMPLE_BEFORE_INLINING
  #undef LANG_HOOKS_CALLGRAPH_EXPAND_FUNCTION
  
--- 123,126 ----
*************** static void gfc_expand_function (tree);
*** 142,146 ****
  #define LANG_HOOKS_SIGNED_TYPE             gfc_signed_type
  #define LANG_HOOKS_SIGNED_OR_UNSIGNED_TYPE gfc_signed_or_unsigned_type
- #define LANG_HOOKS_GIMPLE_BEFORE_INLINING false
  #define LANG_HOOKS_CALLGRAPH_EXPAND_FUNCTION gfc_expand_function
  
--- 141,144 ----
*** fortran/trans-array.c	3 Jun 2004 22:01:10 -0000	1.6
--- fortran/trans-array.c	21 Jun 2004 22:53:05 -0000
*************** gfc_conv_descriptor_data (tree desc)
*** 190,194 ****
  	  && TREE_CODE (TREE_TYPE (TREE_TYPE (field))) == ARRAY_TYPE);
  
!   return build (COMPONENT_REF, TREE_TYPE (field), desc, field);
  }
  
--- 190,194 ----
  	  && TREE_CODE (TREE_TYPE (TREE_TYPE (field))) == ARRAY_TYPE);
  
!   return build (COMPONENT_REF, TREE_TYPE (field), desc, field, NULL_TREE);
  }
  
*************** gfc_conv_descriptor_offset (tree desc)
*** 205,209 ****
    assert (field != NULL_TREE && TREE_TYPE (field) == gfc_array_index_type);
  
!   return build (COMPONENT_REF, TREE_TYPE (field), desc, field);
  }
  
--- 205,209 ----
    assert (field != NULL_TREE && TREE_TYPE (field) == gfc_array_index_type);
  
!   return build (COMPONENT_REF, TREE_TYPE (field), desc, field, NULL_TREE);
  }
  
*************** gfc_conv_descriptor_dtype (tree desc)
*** 220,224 ****
    assert (field != NULL_TREE && TREE_TYPE (field) == gfc_array_index_type);
  
!   return build (COMPONENT_REF, TREE_TYPE (field), desc, field);
  }
  
--- 220,224 ----
    assert (field != NULL_TREE && TREE_TYPE (field) == gfc_array_index_type);
  
!   return build (COMPONENT_REF, TREE_TYPE (field), desc, field, NULL_TREE);
  }
  
*************** gfc_conv_descriptor_dimension (tree desc
*** 238,242 ****
  	  && TREE_CODE (TREE_TYPE (TREE_TYPE (field))) == RECORD_TYPE);
  
!   tmp = build (COMPONENT_REF, TREE_TYPE (field), desc, field);
    tmp = gfc_build_array_ref (tmp, dim);
    return tmp;
--- 238,242 ----
  	  && TREE_CODE (TREE_TYPE (TREE_TYPE (field))) == RECORD_TYPE);
  
!   tmp = build (COMPONENT_REF, TREE_TYPE (field), desc, field, NULL_TREE);
    tmp = gfc_build_array_ref (tmp, dim);
    return tmp;
*************** gfc_conv_descriptor_stride (tree desc, t
*** 254,258 ****
    assert (field != NULL_TREE && TREE_TYPE (field) == gfc_array_index_type);
  
!   tmp = build (COMPONENT_REF, TREE_TYPE (field), tmp, field);
    return tmp;
  }
--- 254,258 ----
    assert (field != NULL_TREE && TREE_TYPE (field) == gfc_array_index_type);
  
!   tmp = build (COMPONENT_REF, TREE_TYPE (field), tmp, field, NULL_TREE);
    return tmp;
  }
*************** gfc_conv_descriptor_lbound (tree desc, t
*** 269,273 ****
    assert (field != NULL_TREE && TREE_TYPE (field) == gfc_array_index_type);
  
!   tmp = build (COMPONENT_REF, TREE_TYPE (field), tmp, field);
    return tmp;
  }
--- 269,273 ----
    assert (field != NULL_TREE && TREE_TYPE (field) == gfc_array_index_type);
  
!   tmp = build (COMPONENT_REF, TREE_TYPE (field), tmp, field, NULL_TREE);
    return tmp;
  }
*************** gfc_conv_descriptor_ubound (tree desc, t
*** 284,288 ****
    assert (field != NULL_TREE && TREE_TYPE (field) == gfc_array_index_type);
  
!   tmp = build (COMPONENT_REF, TREE_TYPE (field), tmp, field);
    return tmp;
  }
--- 284,288 ----
    assert (field != NULL_TREE && TREE_TYPE (field) == gfc_array_index_type);
  
!   tmp = build (COMPONENT_REF, TREE_TYPE (field), tmp, field, NULL_TREE);
    return tmp;
  }
*** fortran/trans-common.c	29 May 2004 01:24:15 -0000	1.6
--- fortran/trans-common.c	21 Jun 2004 22:53:05 -0000
*************** create_common (gfc_symbol *sym)
*** 426,430 ****
      {
        h->sym->backend_decl = build (COMPONENT_REF, TREE_TYPE (h->field),
!                                     decl, h->field);
  
        next_s = h->next;
--- 426,430 ----
      {
        h->sym->backend_decl = build (COMPONENT_REF, TREE_TYPE (h->field),
!                                     decl, h->field, NULL_TREE);
  
        next_s = h->next;
*** fortran/trans-decl.c	14 Jun 2004 16:04:41 -0000	1.13
--- fortran/trans-decl.c	21 Jun 2004 22:53:06 -0000
*************** gfc_trans_auto_character_variable (gfc_s
*** 1646,1649 ****
--- 1646,1657 ----
    DECL_DEFER_OUTPUT (decl) = 1;
  
+   /* Since we don't use a DECL_STMT or equivalent, we have to deal
+      with getting these gimplified.  But we can't gimplify it yet since
+      we're still generating statements.
+ 
+      ??? This should be cleaned up and handled like other front ends.  */
+   gfc_add_expr_to_block (&body, save_expr (DECL_SIZE (decl)));
+   gfc_add_expr_to_block (&body, save_expr (DECL_SIZE_UNIT (decl)));
+ 
    /* Generate code to allocate the automatic variable.  It will be freed
       automatically.  */
*************** gfc_finalize (tree decl)
*** 1950,1953 ****
--- 1958,1979 ----
  }
  
+ /* Convert FNDECL's code to GIMPLE and handle any nested functions.  */
+ 
+ static void
+ gfc_gimplify_function (tree fndecl)
+ {
+   struct cgraph_node *cgn;
+ 
+   gimplify_function_tree (fndecl);
+   dump_function (TDI_generic, fndecl);
+ 
+   /* Convert all nested functions to GIMPLE now.  We do things in this order
+      so that items like VLA sizes are expanded properly in the context of the
+      correct function.  */
+   cgn = cgraph_node (fndecl);
+   for (cgn = cgn->nested; cgn; cgn = cgn->next_nested)
+     gfc_gimplify_function (cgn->decl);
+ }
+ 
  /* Generate code for a function.  */
  
*************** gfc_generate_function_code (gfc_namespac
*** 2121,2144 ****
  
    if (decl_function_context (fndecl))
!     {
!       /* Register this function with cgraph just far enough to get it
! 	 added to our parent's nested function list.  */
!       (void) cgraph_node (fndecl);
! 
!       /* Lowering nested functions requires gimple input.  */
!       gimplify_function_tree (fndecl);
!     }
    else
      {
!       if (cgraph_node (fndecl)->nested)
! 	{
! 	  gimplify_function_tree (fndecl);
!           lower_nested_functions (fndecl);
! 	}
        gfc_finalize (fndecl);
      }
  }
  
- 
  void
  gfc_generate_constructors (void)
--- 2147,2161 ----
  
    if (decl_function_context (fndecl))
!     /* Register this function with cgraph just far enough to get it
!        added to our parent's nested function list.  */
!     (void) cgraph_node (fndecl);
    else
      {
!       gfc_gimplify_function (fndecl);
!       lower_nested_functions (fndecl);
        gfc_finalize (fndecl);
      }
  }
  
  void
  gfc_generate_constructors (void)
diff -c -2 -p -r1.10 trans-expr.c
*** fortran/trans-expr.c	12 Jun 2004 14:06:18 -0000	1.10
--- fortran/trans-expr.c	21 Jun 2004 22:53:07 -0000
*************** gfc_conv_component_ref (gfc_se * se, gfc
*** 222,226 ****
    assert (TREE_CODE (field) == FIELD_DECL);
    decl = se->expr;
!   tmp = build (COMPONENT_REF, TREE_TYPE (field), decl, field);
  
    se->expr = tmp;
--- 222,226 ----
    assert (TREE_CODE (field) == FIELD_DECL);
    decl = se->expr;
!   tmp = build (COMPONENT_REF, TREE_TYPE (field), decl, field, NULL_TREE);
  
    se->expr = tmp;
*** fortran/trans-io.c	15 May 2004 17:31:32 -0000	1.5
--- fortran/trans-io.c	21 Jun 2004 22:53:07 -0000
*************** set_parameter_value (stmtblock_t * block
*** 346,350 ****
    gfc_add_block_to_block (block, &se.pre);
  
!   tmp = build (COMPONENT_REF, TREE_TYPE (var), ioparm_var, var);
    gfc_add_modify_expr (block, tmp, se.expr);
  }
--- 346,350 ----
    gfc_add_block_to_block (block, &se.pre);
  
!   tmp = build (COMPONENT_REF, TREE_TYPE (var), ioparm_var, var, NULL_TREE);
    gfc_add_modify_expr (block, tmp, se.expr);
  }
*************** set_parameter_ref (stmtblock_t * block, 
*** 366,370 ****
    gfc_add_block_to_block (block, &se.pre);
  
!   tmp = build (COMPONENT_REF, TREE_TYPE (var), ioparm_var, var);
    gfc_add_modify_expr (block, tmp, se.expr);
  }
--- 366,370 ----
    gfc_add_block_to_block (block, &se.pre);
  
!   tmp = build (COMPONENT_REF, TREE_TYPE (var), ioparm_var, var, NULL_TREE);
    gfc_add_modify_expr (block, tmp, se.expr);
  }
*************** set_string (stmtblock_t * block, stmtblo
*** 387,392 ****
    gfc_conv_expr (&se, e);
  
!   io = build (COMPONENT_REF, TREE_TYPE (var), ioparm_var, var);
!   len = build (COMPONENT_REF, TREE_TYPE (var_len), ioparm_var, var_len);
  
    /*  Integer variable assigned a format label.  */
--- 387,393 ----
    gfc_conv_expr (&se, e);
  
!   io = build (COMPONENT_REF, TREE_TYPE (var), ioparm_var, var, NULL_TREE);
!   len = build (COMPONENT_REF, TREE_TYPE (var_len), ioparm_var, var_len,
! 	       NULL_TREE);
  
    /*  Integer variable assigned a format label.  */
*************** set_flag (stmtblock_t *block, tree var)
*** 420,424 ****
    tree tmp;
  
!   tmp = build (COMPONENT_REF, TREE_TYPE(var), ioparm_var, var);
    gfc_add_modify_expr (block, tmp, integer_one_node);
  }
--- 421,425 ----
    tree tmp;
  
!   tmp = build (COMPONENT_REF, TREE_TYPE(var), ioparm_var, var, NULL_TREE);
    gfc_add_modify_expr (block, tmp, integer_one_node);
  }
*************** io_result (stmtblock_t * block, gfc_st_l
*** 483,487 ****
  
    rc = build (COMPONENT_REF, TREE_TYPE (ioparm_library_return), ioparm_var,
! 	      ioparm_library_return);
  
    tmp = build_v (SWITCH_EXPR, rc, tmp, NULL_TREE);
--- 484,488 ----
  
    rc = build (COMPONENT_REF, TREE_TYPE (ioparm_library_return), ioparm_var,
! 	      ioparm_library_return, NULL_TREE);
  
    tmp = build_v (SWITCH_EXPR, rc, tmp, NULL_TREE);
*************** transfer_expr (gfc_se * se, gfc_typespec
*** 1066,1070 ****
  	  assert (field && TREE_CODE (field) == FIELD_DECL);
  
! 	  tmp = build (COMPONENT_REF, TREE_TYPE (field), expr, field);
  
  	  if (c->ts.type == BT_CHARACTER)
--- 1067,1072 ----
  	  assert (field && TREE_CODE (field) == FIELD_DECL);
  
! 	  tmp = build (COMPONENT_REF, TREE_TYPE (field), expr, field,
! 		       NULL_TREE);
  
  	  if (c->ts.type == BT_CHARACTER)
*** fortran/trans.c	3 Jun 2004 21:56:54 -0000	1.7
--- fortran/trans.c	21 Jun 2004 22:53:08 -0000
*************** gfc_build_array_ref (tree base, tree off
*** 307,311 ****
      TREE_ADDRESSABLE (base) = 1;
  
!   return build (ARRAY_REF, type, base, offset);
  }
  
--- 307,311 ----
      TREE_ADDRESSABLE (base) = 1;
  
!   return build (ARRAY_REF, type, base, offset, NULL_TREE, NULL_TREE);
  }
  
*** java/class.c	16 Jun 2004 07:25:53 -0000	1.186
--- java/class.c	21 Jun 2004 22:53:09 -0000
*************** build_class_ref (tree type)
*** 1024,1028 ****
  	      prim_class = lookup_class (get_identifier (prim_class_name));
  	      return build (COMPONENT_REF, NULL_TREE,
! 			    prim_class, TYPE_identifier_node);
  	    }
  	  decl_name = TYPE_NAME (type);
--- 1024,1028 ----
  	      prim_class = lookup_class (get_identifier (prim_class_name));
  	      return build (COMPONENT_REF, NULL_TREE,
! 			    prim_class, TYPE_identifier_node, NULL_TREE);
  	    }
  	  decl_name = TYPE_NAME (type);
*************** build_static_field_ref (tree fdecl)
*** 1089,1093 ****
        tree field_address
  	= build (ARRAY_REF, build_pointer_type (TREE_TYPE (fdecl)), 
! 		 TYPE_ATABLE_DECL (output_class), table_index);
        return fold (build1 (INDIRECT_REF, TREE_TYPE (fdecl), 
  			   field_address));
--- 1089,1094 ----
        tree field_address
  	= build (ARRAY_REF, build_pointer_type (TREE_TYPE (fdecl)), 
! 		 TYPE_ATABLE_DECL (output_class), table_index,
! 		 NULL_TREE, NULL_TREE);
        return fold (build1 (INDIRECT_REF, TREE_TYPE (fdecl), 
  			   field_address));
*************** build_static_field_ref (tree fdecl)
*** 1102,1106 ****
        ref = build1 (INDIRECT_REF, class_type_node, ref);
        ref = build (COMPONENT_REF, field_ptr_type_node, ref,
! 		   lookup_field (&class_type_node, fields_ident));
  
        for (fld = TYPE_FIELDS (fclass); ; fld = TREE_CHAIN (fld))
--- 1103,1108 ----
        ref = build1 (INDIRECT_REF, class_type_node, ref);
        ref = build (COMPONENT_REF, field_ptr_type_node, ref,
! 		   lookup_field (&class_type_node, fields_ident),
! 		   NULL_TREE);
  
        for (fld = TYPE_FIELDS (fclass); ; fld = TREE_CHAIN (fld))
*************** build_static_field_ref (tree fdecl)
*** 1119,1125 ****
        ref = build1 (INDIRECT_REF, field_type_node, ref);
        ref = build (COMPONENT_REF, field_info_union_node,
! 		   ref, lookup_field (&field_type_node, info_ident));
        ref = build (COMPONENT_REF, ptr_type_node,
! 		   ref, TREE_CHAIN (TYPE_FIELDS (field_info_union_node)));
        return fold (build1 (INDIRECT_REF, TREE_TYPE(fdecl), ref));
      }
--- 1121,1129 ----
        ref = build1 (INDIRECT_REF, field_type_node, ref);
        ref = build (COMPONENT_REF, field_info_union_node,
! 		   ref, lookup_field (&field_type_node, info_ident),
! 		   NULL_TREE);
        ref = build (COMPONENT_REF, ptr_type_node,
! 		   ref, TREE_CHAIN (TYPE_FIELDS (field_info_union_node)),
! 		   NULL_TREE);
        return fold (build1 (INDIRECT_REF, TREE_TYPE(fdecl), ref));
      }
*** java/constants.c	13 May 2004 06:40:34 -0000	1.34
--- java/constants.c	21 Jun 2004 22:53:10 -0000
*************** build_ref_from_constant_pool (int index)
*** 425,429 ****
    tree d = build_constant_data_ref ();
    tree i = build_int_2 (index, 0);
!   return build (ARRAY_REF, TREE_TYPE (TREE_TYPE (d)), d, i);
  }
  
--- 425,430 ----
    tree d = build_constant_data_ref ();
    tree i = build_int_2 (index, 0);
!   return build (ARRAY_REF, TREE_TYPE (TREE_TYPE (d)), d, i,
! 		NULL_TREE, NULL_TREE);
  }
  
*** java/expr.c	8 Jun 2004 13:27:38 -0000	1.192
--- java/expr.c	21 Jun 2004 22:53:11 -0000
*************** build_java_array_length_access (tree nod
*** 699,703 ****
  		build_java_indirect_ref (array_type, node,
  					 flag_check_references),
! 		lookup_field (&array_type, get_identifier ("length")));
    IS_ARRAY_LENGTH_ACCESS (node) = 1;
    return node;
--- 699,704 ----
  		build_java_indirect_ref (array_type, node,
  					 flag_check_references),
! 		lookup_field (&array_type, get_identifier ("length")),
! 		NULL_TREE);
    IS_ARRAY_LENGTH_ACCESS (node) = 1;
    return node;
*************** build_java_arrayaccess (tree array, tree
*** 781,787 ****
  	       build_java_indirect_ref (array_type, array, 
  					flag_check_references),
! 	       data_field);
    
!   node = build (ARRAY_REF, type, ref, index);
    return node;
  }
--- 782,788 ----
  	       build_java_indirect_ref (array_type, array, 
  					flag_check_references),
! 	       data_field, NULL_TREE);
    
!   node = build (ARRAY_REF, type, ref, index, NULL_TREE, NULL_TREE);
    return node;
  }
*************** build_get_class (tree value)
*** 1182,1187 ****
  			       build_java_indirect_ref (object_type_node, value,
  							flag_check_references),
! 			       vtable_field)),
! 		class_field);
  }
  
--- 1183,1188 ----
  			       build_java_indirect_ref (object_type_node, value,
  							flag_check_references),
! 			       vtable_field, NULL_TREE)),
! 		class_field, NULL_TREE);
  }
  
*************** build_field_ref (tree self_value, tree s
*** 1532,1542 ****
  	   we can make a direct reference.  */
  	{
! 	  tree otable_index =
! 	    build_int_2 (get_symbol_table_index 
! 			 (field_decl, &TYPE_OTABLE_METHODS (output_class)), 0);
! 	  tree field_offset = 
! 	    build (ARRAY_REF, integer_type_node, TYPE_OTABLE_DECL (output_class), 
! 		   otable_index);
  	  tree address;
  	  field_offset = fold (convert (sizetype, field_offset));
  	  address 
--- 1533,1546 ----
  	   we can make a direct reference.  */
  	{
! 	  tree otable_index
! 	    = build_int_2 (get_symbol_table_index 
! 			   (field_decl, &TYPE_OTABLE_METHODS (output_class)),
! 			   0);
! 	  tree field_offset
! 	    = build (ARRAY_REF, integer_type_node,
! 		     TYPE_OTABLE_DECL (output_class), otable_index,
! 		     NULL_TREE, NULL_TREE);
  	  tree address;
+ 
  	  field_offset = fold (convert (sizetype, field_offset));
  	  address 
*************** build_field_ref (tree self_value, tree s
*** 1550,1554 ****
  					    self_value, check);
        return fold (build (COMPONENT_REF, TREE_TYPE (field_decl),
! 			  self_value, field_decl));
      }
  }
--- 1554,1558 ----
  					    self_value, check);
        return fold (build (COMPONENT_REF, TREE_TYPE (field_decl),
! 			  self_value, field_decl, NULL_TREE));
      }
  }
*************** build_known_method_ref (tree method, tre
*** 1827,1836 ****
        else
  	{
! 	  tree table_index = 
! 	    build_int_2 (get_symbol_table_index 
! 			 (method, &TYPE_ATABLE_METHODS (output_class)), 0);
! 	  func = 
! 	    build (ARRAY_REF,  method_ptr_type_node, 
! 		   TYPE_ATABLE_DECL (output_class), table_index);
  	}
        func = convert (method_ptr_type_node, func);
--- 1831,1840 ----
        else
  	{
! 	  tree table_index
! 	    = build_int_2 (get_symbol_table_index 
! 			   (method, &TYPE_ATABLE_METHODS (output_class)), 0);
! 	  func = build (ARRAY_REF,  method_ptr_type_node, 
! 			TYPE_ATABLE_DECL (output_class), table_index,
! 			NULL_TREE, NULL_TREE);
  	}
        func = convert (method_ptr_type_node, func);
*************** build_known_method_ref (tree method, tre
*** 1859,1863 ****
  	methods_ident = get_identifier ("methods");
        ref = build (COMPONENT_REF, method_ptr_type_node, ref,
! 		   lookup_field (&class_type_node, methods_ident));
        for (meth = TYPE_METHODS (self_type);
  	   ; meth = TREE_CHAIN (meth))
--- 1863,1867 ----
  	methods_ident = get_identifier ("methods");
        ref = build (COMPONENT_REF, method_ptr_type_node, ref,
! 		   lookup_field (&class_type_node, methods_ident), NULL_TREE);
        for (meth = TYPE_METHODS (self_type);
  	   ; meth = TREE_CHAIN (meth))
*************** build_known_method_ref (tree method, tre
*** 1875,1880 ****
        ref = build1 (INDIRECT_REF, method_type_node, ref);
        func = build (COMPONENT_REF, nativecode_ptr_type_node,
! 		    ref,
! 		    lookup_field (&method_type_node, ncode_ident));
      }
    return func;
--- 1879,1884 ----
        ref = build1 (INDIRECT_REF, method_type_node, ref);
        func = build (COMPONENT_REF, nativecode_ptr_type_node,
! 		    ref, lookup_field (&method_type_node, ncode_ident),
! 		    NULL_TREE);
      }
    return func;
*************** invoke_build_dtable (int is_invoke_inter
*** 1900,1904 ****
  				    flag_check_references);
    dtable = build (COMPONENT_REF, dtable_ptr_type, dtable,
! 		  lookup_field (&object_type_node, dtable_ident));
  
    return dtable;
--- 1904,1908 ----
  				    flag_check_references);
    dtable = build (COMPONENT_REF, dtable_ptr_type, dtable,
! 		  lookup_field (&object_type_node, dtable_ident), NULL_TREE);
  
    return dtable;
*************** build_invokevirtual (tree dtable, tree m
*** 1956,1960 ****
        method_index = build (ARRAY_REF, integer_type_node, 
  			    TYPE_OTABLE_DECL (output_class), 
! 			    otable_index);
      }
    else
--- 1960,1964 ----
        method_index = build (ARRAY_REF, integer_type_node, 
  			    TYPE_OTABLE_DECL (output_class), 
! 			    otable_index, NULL_TREE, NULL_TREE);
      }
    else
*************** build_invokeinterface (tree dtable, tree
*** 2002,2006 ****
  				    flag_check_references);
    dtable = build (COMPONENT_REF, class_ptr_type, dtable,
! 		  lookup_field (&dtable_type, class_ident));
  
    interface = DECL_CONTEXT (method);
--- 2006,2010 ----
  				    flag_check_references);
    dtable = build (COMPONENT_REF, class_ptr_type, dtable,
! 		  lookup_field (&dtable_type, class_ident), NULL_TREE);
  
    interface = DECL_CONTEXT (method);
*************** build_invokeinterface (tree dtable, tree
*** 2011,2025 ****
    if (flag_indirect_dispatch)
      {
!       otable_index =
! 	build_int_2 (get_symbol_table_index 
! 		     (method, &TYPE_OTABLE_METHODS (output_class)), 0);
!       idx = 
! 	build (ARRAY_REF, integer_type_node, TYPE_OTABLE_DECL (output_class),
! 	       otable_index);
      }
    else
!     {
!       idx = build_int_2 (get_interface_method_index (method, interface), 0);
!     }
  
    lookup_arg = tree_cons (NULL_TREE, dtable,
--- 2015,2027 ----
    if (flag_indirect_dispatch)
      {
!       otable_index
! 	= build_int_2 (get_symbol_table_index 
! 		       (method, &TYPE_OTABLE_METHODS (output_class)), 0);
!       idx = build (ARRAY_REF, integer_type_node,
! 		   TYPE_OTABLE_DECL (output_class), otable_index,
! 		   NULL_TREE, NULL_TREE);
      }
    else
!     idx = build_int_2 (get_interface_method_index (method, interface), 0);
  
    lookup_arg = tree_cons (NULL_TREE, dtable,
*************** java_expand_expr (tree exp, rtx target, 
*** 2578,2582 ****
  				  build_java_indirect_ref (array_type, 
  					  array_decl, flag_check_references), 
! 				  data_fld), init, 0);
  	return tmp;
        }
--- 2580,2585 ----
  				  build_java_indirect_ref (array_type, 
  					  array_decl, flag_check_references), 
! 				  data_fld, NULL_TREE),
! 			   init, 0);
  	return tmp;
        }
*************** emit_init_test_initialization (void **en
*** 3461,3465 ****
  			build1 (INDIRECT_REF, class_type_node, klass),
  			lookup_field (&class_type_node,
! 				      get_identifier ("state"))),
  		 build_int_2 (JV_STATE_DONE, 0));
  
--- 3464,3469 ----
  			build1 (INDIRECT_REF, class_type_node, klass),
  			lookup_field (&class_type_node,
! 				      get_identifier ("state")),
! 			NULL_TREE),
  		 build_int_2 (JV_STATE_DONE, 0));
  
*** java/java-gimplify.c	21 Jun 2004 16:55:07 -0000	1.5
--- java/java-gimplify.c	21 Jun 2004 22:53:15 -0000
*************** java_gimplify_new_array_init (tree exp)
*** 224,231 ****
        tree lhs = build (COMPONENT_REF, TREE_TYPE (data_field),    
  			build_java_indirect_ref (array_type, tmp, 0),
! 			data_field);
        tree assignment = build (MODIFY_EXPR, element_type,
    			       build (ARRAY_REF, element_type, lhs,
! 				      build_int_2 (index++, 0)),
  			       TREE_VALUE (values));
        body = build (COMPOUND_EXPR, element_type, body, assignment);
--- 223,231 ----
        tree lhs = build (COMPONENT_REF, TREE_TYPE (data_field),    
  			build_java_indirect_ref (array_type, tmp, 0),
! 			data_field, NULL_TREE);
        tree assignment = build (MODIFY_EXPR, element_type,
    			       build (ARRAY_REF, element_type, lhs,
! 				      build_int_2 (index++, 0),
! 				      NULL_TREE, NULL_TREE),
  			       TREE_VALUE (values));
        body = build (COMPOUND_EXPR, element_type, body, assignment);
*** java/parse.y	17 Jun 2004 13:45:23 -0000	1.481
--- java/parse.y	21 Jun 2004 22:53:22 -0000
*************** make_qualified_name (tree left, tree rig
*** 9255,9259 ****
  {
  #ifdef USE_COMPONENT_REF
!   tree node = build (COMPONENT_REF, NULL_TREE, left, right);
    EXPR_WFL_LINECOL (node) = location;
    return node;
--- 9255,9259 ----
  {
  #ifdef USE_COMPONENT_REF
!   tree node = build (COMPONENT_REF, NULL_TREE, left, right, NULL_TREE);
    EXPR_WFL_LINECOL (node) = location;
    return node;
*************** static tree
*** 14354,14358 ****
  build_array_ref (int location, tree array, tree index)
  {
!   tree node = build (ARRAY_REF, NULL_TREE, array, index);
    EXPR_WFL_LINECOL (node) = location;
    return node;
--- 14354,14358 ----
  build_array_ref (int location, tree array, tree index)
  {
!   tree node = build (ARRAY_REF, NULL_TREE, array, index, NULL_TREE, NULL_TREE);
    EXPR_WFL_LINECOL (node) = location;
    return node;
*** objc/objc-act.c	21 Jun 2004 09:15:25 -0000	1.224
--- objc/objc-act.c	21 Jun 2004 22:53:28 -0000
*************** generate_static_references (void)
*** 1976,1980 ****
        ident = get_identifier (buf);
  
!       expr_decl = build_nt (ARRAY_REF, ident, NULL_TREE);
        decl_spec = tree_cons (NULL_TREE, build_pointer_type (void_type_node),
  			     build_tree_list (NULL_TREE,
--- 1976,1980 ----
        ident = get_identifier (buf);
  
!       expr_decl = build_nt (ARRAY_REF, ident, NULL_TREE, NULL_TREE, NULL_TREE);
        decl_spec = tree_cons (NULL_TREE, build_pointer_type (void_type_node),
  			     build_tree_list (NULL_TREE,
*************** generate_static_references (void)
*** 2015,2019 ****
    decls = tree_cons (NULL_TREE, build_int_2 (0, 0), decls);
    ident = get_identifier ("_OBJC_STATIC_INSTANCES");
!   expr_decl = build_nt (ARRAY_REF, ident, NULL_TREE);
    decl_spec = tree_cons (NULL_TREE, build_pointer_type (void_type_node),
  			 build_tree_list (NULL_TREE,
--- 2015,2019 ----
    decls = tree_cons (NULL_TREE, build_int_2 (0, 0), decls);
    ident = get_identifier ("_OBJC_STATIC_INSTANCES");
!   expr_decl = build_nt (ARRAY_REF, ident, NULL_TREE, NULL_TREE, NULL_TREE);
    decl_spec = tree_cons (NULL_TREE, build_pointer_type (void_type_node),
  			 build_tree_list (NULL_TREE,
*************** generate_strings (void)
*** 2045,2049 ****
  	= tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
        decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
!       expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
        decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
        DECL_CONTEXT (decl) = NULL_TREE;
--- 2045,2050 ----
  	= tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
        decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
!       expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE,
! 			    NULL_TREE, NULL_TREE);
        decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
        DECL_CONTEXT (decl) = NULL_TREE;
*************** generate_strings (void)
*** 2060,2064 ****
  	= tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
        decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
!       expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
        decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
        DECL_CONTEXT (decl) = NULL_TREE;
--- 2061,2066 ----
  	= tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
        decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
!       expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE,
! 			    NULL_TREE, NULL_TREE);
        decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
        DECL_CONTEXT (decl) = NULL_TREE;
*************** generate_strings (void)
*** 2075,2079 ****
  	= tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
        decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
!       expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
        decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
        DECL_CONTEXT (decl) = NULL_TREE;
--- 2077,2082 ----
  	= tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
        decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
!       expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE,
! 			    NULL_TREE, NULL_TREE);
        decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
        DECL_CONTEXT (decl) = NULL_TREE;
*************** build_method_prototype_list_template (tr
*** 3522,3526 ****
    decl_specs = build_tree_list (NULL_TREE, list_type);
    field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"),
! 			 build_int_2 (size, 0));
    field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
    chainon (field_decl_chain, field_decl);
--- 3525,3529 ----
    decl_specs = build_tree_list (NULL_TREE, list_type);
    field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"),
! 			 build_int_2 (size, 0), NULL_TREE, NULL_TREE);
    field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
    chainon (field_decl_chain, field_decl);
*************** build_ivar_list_template (tree list_type
*** 4406,4410 ****
    decl_specs = build_tree_list (NULL_TREE, list_type);
    field_decl = build_nt (ARRAY_REF, get_identifier ("ivar_list"),
! 			 build_int_2 (size, 0));
  
    field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
--- 4409,4413 ----
    decl_specs = build_tree_list (NULL_TREE, list_type);
    field_decl = build_nt (ARRAY_REF, get_identifier ("ivar_list"),
! 			 build_int_2 (size, 0), NULL_TREE, NULL_TREE);
  
    field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
*************** build_method_list_template (tree list_ty
*** 4454,4458 ****
    decl_specs = build_tree_list (NULL_TREE, list_type);
    field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"),
! 			 build_int_2 (size, 0));
  
    field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
--- 4457,4461 ----
    decl_specs = build_tree_list (NULL_TREE, list_type);
    field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"),
! 			 build_int_2 (size, 0), NULL_TREE, NULL_TREE);
  
    field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
*************** generate_protocol_list (tree i_or_p)
*** 4861,4870 ****
  			  synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS",
  						      i_or_p),
! 			  build_int_2 (size + 2, 0));
    else if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE)
      expr_decl = build_nt (ARRAY_REF,
  			  synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS",
  						      i_or_p),
! 			  build_int_2 (size + 2, 0));
    else if (TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
      expr_decl
--- 4864,4873 ----
  			  synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS",
  						      i_or_p),
! 			  build_int_2 (size + 2, 0), NULL_TREE, NULL_TREE);
    else if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE)
      expr_decl = build_nt (ARRAY_REF,
  			  synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS",
  						      i_or_p),
! 			  build_int_2 (size + 2, 0), NULL_TREE, NULL_TREE);
    else if (TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
      expr_decl
*************** generate_protocol_list (tree i_or_p)
*** 4872,4876 ****
  		  synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS",
  					      i_or_p),
! 		  build_int_2 (size + 2, 0));
    else
      abort ();
--- 4875,4879 ----
  		  synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS",
  					      i_or_p),
! 		  build_int_2 (size + 2, 0), NULL_TREE, NULL_TREE);
    else
      abort ();

^ permalink raw reply	[flat|nested] 77+ messages in thread

end of thread, other threads:[~2004-07-29 11:34 UTC | newest]

Thread overview: 77+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-06-22 20:22 Patch to allow Ada to work with tree-ssa Richard Kenner
2004-06-22 20:30 ` Mark Mitchell
  -- strict thread matches above, loose matches on Subject: below --
2004-07-29 19:02 Richard Kenner
2004-07-29 18:43 Richard Kenner
2004-07-29 17:12 Richard Kenner
2004-07-29 17:13 ` Diego Novillo
2004-07-29 17:57 ` Richard Henderson
2004-06-25 15:28 Richard Kenner
2004-06-28 15:09 ` Paolo Bonzini
2004-06-24 15:58 Richard Kenner
2004-06-24 16:04 ` Nathan Sidwell
2004-06-25 14:43 ` Joseph S. Myers
2004-06-23  5:54 Richard Kenner
2004-06-23  2:32 Richard Kenner
2004-06-23  4:54 ` Bryce McKinlay
2004-06-23  0:16 Richard Kenner
2004-06-22 23:05 Richard Kenner
2004-06-23 11:42 ` Nathan Sidwell
2004-06-22 22:18 Richard Kenner
2004-06-23  1:07 ` Richard Henderson
2004-06-22 21:30 Richard Kenner
2004-06-22 22:04 ` Paul Brook
2004-06-22 21:27 Richard Kenner
2004-06-22 21:29 ` Mark Mitchell
2004-06-22 21:10 Richard Kenner
2004-06-22 21:12 ` Mark Mitchell
2004-06-22 22:16 ` Daniel Berlin
2004-06-22 21:07 Richard Kenner
2004-06-22 21:12 ` Bryce McKinlay
2004-06-22 21:05 Richard Kenner
2004-06-22 21:01 Richard Kenner
2004-06-22 20:54 Richard Kenner
2004-06-22 21:06 ` Paul Brook
2004-06-22 21:37 ` Richard Henderson
2004-06-22 20:44 Richard Kenner
2004-06-22 21:03 ` Mark Mitchell
2004-06-23 20:58 ` Geoffrey Keating
2004-06-22 20:40 Richard Kenner
2004-06-22 22:02 ` Nathan Sidwell
2004-06-22 22:27   ` Joseph S. Myers
2004-06-22 20:23 Richard Kenner
2004-06-22 20:37 ` Joseph S. Myers
2004-06-23 20:47 ` Geoffrey Keating
2004-06-24 14:59   ` Joseph S. Myers
2004-06-24 16:26     ` Richard Earnshaw
2004-06-24 19:57       ` Laurent GUERBY
2004-06-24 20:06         ` Diego Novillo
2004-06-24 20:24           ` Andrew Pinski
2004-06-24 22:35             ` Laurent GUERBY
2004-06-24 21:33           ` Laurent GUERBY
2004-06-24 21:01         ` Joseph S. Myers
2004-06-25 14:51         ` Richard Earnshaw
2004-06-22 19:05 Richard Kenner
2004-06-22 20:10 ` Joseph S. Myers
2004-06-22 20:27 ` Andrew Haley
     [not found] <10406221359.AA05860@vlsi1.ultra.nyu.edu>
2004-06-22 18:47 ` Richard Henderson
2004-06-22 18:33 Richard Kenner
2004-06-22 18:19 Richard Kenner
2004-06-22 18:36 ` Nathan Sidwell
2004-06-22 18:37   ` Nathan Sidwell
2004-06-22 18:45 ` Mark Mitchell
2004-06-22 17:05 Richard Kenner
2004-06-22 17:21 ` Andrew Haley
2004-06-22 19:01   ` Richard Henderson
2004-06-22 16:34 Richard Kenner
2004-06-22 16:33 Richard Kenner
2004-06-22 17:46 ` Mark Mitchell
2004-06-22 18:17   ` Joseph S. Myers
2004-06-22 18:52   ` Richard Henderson
2004-06-22 19:37     ` Zack Weinberg
2004-06-22  7:05 Richard Kenner
2004-06-22  7:29 ` Mark Mitchell
2004-06-22  9:14   ` Andrew Pinski
2004-06-22 14:16   ` Andrew Haley
2004-06-22 11:00 ` Richard Henderson
2004-06-22 13:52 ` Ranjit Mathew
2004-07-29 17:02 ` Diego Novillo

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).