public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* Re: [patch] for PR 18040
@ 2004-10-18 17:48 Richard Kenner
  0 siblings, 0 replies; 61+ messages in thread
From: Richard Kenner @ 2004-10-18 17:48 UTC (permalink / raw)
  To: fw; +Cc: gcc-patches

    The language permits to work on an addressable copy instead, 

Yes, but (1) that copy can be very large and (2) there is also a use
of a VIEW_CONVERT_EXPR on inside the nest of references in the LHS
where the copy isn't permitted.

^ permalink raw reply	[flat|nested] 61+ messages in thread
* Re: [patch] for PR 18040
@ 2004-10-20 13:27 Richard Kenner
  0 siblings, 0 replies; 61+ messages in thread
From: Richard Kenner @ 2004-10-20 13:27 UTC (permalink / raw)
  To: jason; +Cc: gcc-patches

    But we should only allow VIEW_CONVERT_EXPR, not NOP_EXPR or any other
    conversion codes.

I agree.  I think the others are historical at this point and not
actually used.

^ permalink raw reply	[flat|nested] 61+ messages in thread
* Re: [patch] for PR 18040
@ 2004-10-20  0:25 Richard Kenner
  0 siblings, 0 replies; 61+ messages in thread
From: Richard Kenner @ 2004-10-20  0:25 UTC (permalink / raw)
  To: rth; +Cc: gcc-patches

    Folks that abuse unchecked_conversion like this get what they deserve.

Perhaps, though I doubt many would see it that way.  But the more
significant point is that VIEW_CONVERT_EXPR occurs in generated trees
for lots of operations, such as object-oriented stuff, that we do
want to operate efficiently.

^ permalink raw reply	[flat|nested] 61+ messages in thread
* Re: [patch] for PR 18040
@ 2004-10-19 23:26 Richard Kenner
  0 siblings, 0 replies; 61+ messages in thread
From: Richard Kenner @ 2004-10-19 23:26 UTC (permalink / raw)
  To: jason; +Cc: gcc-patches

    a.b.c would still be valid GIMPLE, but the initial gimplification may break
    it down in future.  A later pass would be free to put it back together.

I have no problem with that.  However, I though the purpose of the
proposal was to make it *not* valid GIMPLE.  Of course, until we have a
tree combiner, it's not going to be put back together.

^ permalink raw reply	[flat|nested] 61+ messages in thread
* Re: [patch] for PR 18040
@ 2004-10-19 23:22 Richard Kenner
  0 siblings, 0 replies; 61+ messages in thread
From: Richard Kenner @ 2004-10-19 23:22 UTC (permalink / raw)
  To: zack; +Cc: gcc-patches

    But this problem goes away if you start manipulating all the
    aggregates by reference.  

See my last mesasge on that topic.

    Sure, but this is decidedly _not_ the way the tree optimizers want to
    think about it.  Where RTL requires something to be done a certain
    way, we should not make that into a design constraint on trees; at
    most, there might be an impedance mismatch to be resolved in the
    expander.

Sure, but the point isn't RTL-specific.  It relates to code
generation.  When generating code, you only have to do *one* operation
no matter how many dereferences there are: all the extra defererences
do is change the parameters (offsets in this case) of that operation.
That's why I like to view this nest as conceptually one operation.

    Hmm.  That might turn out to be equivalent to my handwavey suggestion
    of inventing some way to make unaddressable things addressable for
    tree purposes.  Do you have a pointer to that proposal?

I don't think so, but the proposal is at
	http://gcc.gnu.org/ml/gcc/2004-06/msg01376.html

^ permalink raw reply	[flat|nested] 61+ messages in thread
* Re: [patch] for PR 18040
@ 2004-10-19 23:03 Richard Kenner
  2004-10-19 23:13 ` Jason Merrill
  0 siblings, 1 reply; 61+ messages in thread
From: Richard Kenner @ 2004-10-19 23:03 UTC (permalink / raw)
  To: jason; +Cc: gcc-patches

    I don't think anybody is suggesting that we break up reference chains
    in a way that would introduce aggregate temporaries.  Only things that
    can be expressed like

           t = &a.b;
    a.b.c  =>    t->c

    "t" here is a scalar temporary, so the optimizers should be able to do
    useful things with it.

But that has it's own set of problems:

(1) We're taking an address of something that didn't used to have its
address taken.

(2) Suppose a.b is not addressable?  Then you *do* have to make a copy
and hence an aggregate temporary.

If a.b.c is not valid GIMPLE, then even if we had a tree combiner (and
ignoring the nonaddressable issue), we couldn't undo this pessimization.
For example, suppose A were small enough to go into a register.  Taking
the address of a.b would preclude that.

^ permalink raw reply	[flat|nested] 61+ messages in thread
* Re: [patch] for PR 18040
@ 2004-10-19 22:48 Richard Kenner
  2004-10-19 23:01 ` Jason Merrill
  2004-10-19 23:07 ` Zack Weinberg
  0 siblings, 2 replies; 61+ messages in thread
From: Richard Kenner @ 2004-10-19 22:48 UTC (permalink / raw)
  To: zack; +Cc: gcc-patches

    The tree optimizers do better on simple operations, which is why we
    have GIMPLE in the first place.  

Sure, but this begs the question of how we define "simple" ..

    In fact, some people have argued that
    we should be breaking up _all_ chains of dereference operations so
    that the optimizers can see better.

The problem, however, is that the SSA-based optimizations operate mostly
on *scalars*, so making more aggregate temporaries, which is what
happens when you break up those chains, creates things that are hard to
remove under the present optimization environment.

Moreover, some of those temporaries will be of variable-size, which
we don't currently support.

    > No, of course not.  But I thought the idea is to encode each statement as
    > one *expansion* operation.

    I do not understand this statement.

Well, it's indeed not very well-defined, but what I was trying to get at is
that at the level of generating RTL, we treat a chain of reference
operators as if it were one operation, by merging all the offset calculations
into one.  Indeed, I once made a proposal of having a "reference annotation"
that would formalize that approach and, for each dereference operation,
produce a variable that represented the cumulative offset up to that point.
If you do that, then the entire chain really *is* one operation for all
purposes except loop optimizers, which will want to look at array
references.

^ permalink raw reply	[flat|nested] 61+ messages in thread
* Re: [patch] for PR 18040
@ 2004-10-18 15:42 Richard Kenner
  0 siblings, 0 replies; 61+ messages in thread
From: Richard Kenner @ 2004-10-18 15:42 UTC (permalink / raw)
  To: dberlin; +Cc: gcc-patches

    It is much easier to optimize expressions that are simple, regardless 
    of how they are split up, because it makes your optimizers simpler to 
    write, and you are much less likely to miss corner cases, etc.

Sorry, I wasn't asking the general question, but about this specific case.
I'd like to see how it's easier to optimize cases with a conversion between
two field references when they are in two statements than in one.  

^ permalink raw reply	[flat|nested] 61+ messages in thread
* Re: [patch] for PR 18040
@ 2004-10-18 14:52 Richard Kenner
  2004-10-18 15:20 ` Daniel Berlin
  0 siblings, 1 reply; 61+ messages in thread
From: Richard Kenner @ 2004-10-18 14:52 UTC (permalink / raw)
  To: dberlin; +Cc: gcc-patches

    A quick check of a random function handling component_refs shows they
    will also be missing optimizations

Let me be very clear here:

If the nops aren't needed, they won't be there.  So the question isn't
if they are needed or not.  Rather, it's whether the expression should be
split up among statements.

Are you really arguing that it's more likely to miss optimizations if they
are in *one* statement than if they are in multiple statements?  If so,
can you explain?

^ permalink raw reply	[flat|nested] 61+ messages in thread
* Re: [patch] for PR 18040
@ 2004-10-18 14:38 Richard Kenner
  0 siblings, 0 replies; 61+ messages in thread
From: Richard Kenner @ 2004-10-18 14:38 UTC (permalink / raw)
  To: dberlin; +Cc: gcc-patches

    Inserting STRIP_NOPS into everywhere that breaks apart component_refs
    and looking for variables and things is not a pleasant idea, unless it
    was hidden in component_ref iterators of some sort that you could tell
    to auto-skip them (the way we have ssa operand iterators).

Actually, it wouldn't do anything, because it doesn't strip
VIEW_CONVERT_EXPR and only strips those NOP_EXPRs that would have already
been removed!

    Thus, if you want ((cast)var).field to be legal, you are going to have
    to go through every single function in the optimizers that walks
    component_refs and fix them.  A lot of them are simply returning NULL
    or (whatever they have don't know) in the case where they hit the
    NOP_EXPR, instead of aborting.  Some are probably silently doing bad
    things :)

Well, how many of those are there?  Most just treat an "LHS" as a 
single object.  Very few would look inside it.

    This will miss the indirect_ref (and an optimization opportunity) if you
    have COMPONENT_REF <NOP_EXPR <INDIRECT_REF <SSA_NAME>>>AR_DECL>>

But I'm not sure that *is* an optimization opportunity: if that
NOP_EXPR is still there, it's there for a reason!

The question I'd ask is whether you'd have the optimization opportunity if
the NOP_EXPR were in a separate statement.  The answer is clearly "no".
So how would doing that help?

^ permalink raw reply	[flat|nested] 61+ messages in thread
* Re: [patch] for PR 18040
@ 2004-10-18 14:24 Richard Kenner
  2004-10-19 22:50 ` Zack Weinberg
  0 siblings, 1 reply; 61+ messages in thread
From: Richard Kenner @ 2004-10-18 14:24 UTC (permalink / raw)
  To: zack; +Cc: gcc-patches

    If you provide an example which produces a type conversion in the
    middle of a chain of dereference expressions, I will endeavor to
    clarify what I mean.

I'll try, but, as I said, I don't write Ada very well ...

	with unchecked_conversion;
	function foo return integer is
	    type arr is array (1 .. 100) of integer;
	    type r is record
		f1: integer;
		f2: array (1..99) of integer;
	    end record;
	    function uc is new unchecked_conversion (arr, r);
	    type q is record f1: arr; end record;

	    var: q;
	begin
	    return (uc (q.f1).f1;
	end foo;

^ permalink raw reply	[flat|nested] 61+ messages in thread
* Re: [patch] for PR 18040
@ 2004-10-18 14:22 Richard Kenner
  2004-10-19 22:47 ` Zack Weinberg
  0 siblings, 1 reply; 61+ messages in thread
From: Richard Kenner @ 2004-10-18 14:22 UTC (permalink / raw)
  To: zack; +Cc: gcc-patches

[First of all, let me apologize about the lack of threading.  I *do* have
the sources I need to implement that, but I want to catch up on some of
the technical stuff (ACATS bugs) first.]

    Ok.  Does that also address the objection you raised to the
    pointer-punning operation at the outermost level?

The *correctness* objection, yes, but not the code quality objection.  We'd
have a situation where it's impossible for the tree optimizers to improve
the code because there's no way of representing the improvement.  That's bad.

    You'd only need to construct the modified outermost type when you had
    a type conversion somewhere along the chain of references.  I suppose
    one could construct a program that accesses each field *with* a type
    conversion; I can't think of any good reason such a program would pop
    up in the wild, but still, if we can find a solution that doesn't
    entail quadratic behavior for this case that would be good.

Many Ada programs that access each field of a complex record in a nested
way would have such conversions: remember, I said they weren't just there
in explicit user cases, but the front-end inserts such conversions too.
Yes, it may add too many of those and looking into that is certainly on
my list, but this adding yet more complexity to the issue.

    The goal is not to be able to represent as one statement every
    operation that can be encoded in one machine instruction, and it is
    certainly not to be able to represent as one statement every primitive
    operation of every supported language.

No, of course not.  But I thought the idea is to encode each statement as
one *expansion* operation.

^ permalink raw reply	[flat|nested] 61+ messages in thread
* Re: [patch] for PR 18040
@ 2004-10-18  3:12 Richard Kenner
  2004-10-18  4:02 ` Zack Weinberg
  0 siblings, 1 reply; 61+ messages in thread
From: Richard Kenner @ 2004-10-18  3:12 UTC (permalink / raw)
  To: zack; +Cc: gcc-patches

    Your opinion on my alternative suggestion - hoist the type conversion
    to the outermost type, thus reducing the nested case to the unnested
    case - would be appreciated (and please read the whole message before
    answering the question, because I address another objection below).

Aside from the issue of possible quadratic behavior, I don't completely
understand the proposal here, so I can't fully comment on it.  I should
point out, though, that some of these expressions in practice are
quite complex: there are lots of implicit conversions and dereferences
generated by the front end.

    I didn't say this had to be captured in the type-based alias sets, I
    said it had to be comprehensible to the alias analyzer.  Those two
    assertions are not the same thing.

No, but your comment about the GNAT alias set computation was sounding like
you were talking about type-based alias sets.

    > This stuff is *very* tricky and, as I said, we've been throught it
    > before.

    The PR indicates that the solution which has already been implemented
    does not work.  Thus, the entire topic is open for reexamination.

The PR indicates that a particular optimizer has problems with the
overall approach.  One way of dealing with that is to change the approach.
But a more local way is to fix that particular optimizer.

^ permalink raw reply	[flat|nested] 61+ messages in thread
* Re: [patch] for PR 18040
@ 2004-10-18  2:46 Richard Kenner
  0 siblings, 0 replies; 61+ messages in thread
From: Richard Kenner @ 2004-10-18  2:46 UTC (permalink / raw)
  To: zack; +Cc: gcc-patches

    Also, I just now thought of an alternative: whenever you have a chain
    of *_REF expressions which requires a type conversion somewhere along
    the way, construct a modified version of the *outermost* type which
    will give the field in question the effective type that it needs.

That construction operation is linear in the number of fields in the
record.  If you have a program that access each field, doing that
construction produces quadratic behavior (we have such a program in
the testsuite for simple field accesses).

^ permalink raw reply	[flat|nested] 61+ messages in thread
* Re: [patch] for PR 18040
@ 2004-10-18  2:38 Richard Kenner
  2004-10-18  3:14 ` Zack Weinberg
  0 siblings, 1 reply; 61+ messages in thread
From: Richard Kenner @ 2004-10-18  2:38 UTC (permalink / raw)
  To: zack; +Cc: gcc-patches

    Hmm.  Is it possible to construct an example which BOTH requires
    taking the address of an intermediate field, and wouldn't be cured by
    making all *_REF expressions implicitly convert to their type?

Sorry, I didn't realize that you were talking about a different solutions
to each problem.

I believe the answer to the question you pose is "no", but it's going to be
hard to prove that.  There is a potential aliasing problem, but I don't think
it can actually occur because you can always view the semantics of the
VIEW_CONVERT_EXPR as being pointer punning and could make the resulting
pointer TYPE_REF_CAN_ALIAS_ALL.

What I'm not sure about are issues relating to code quality: we've taken what
used to be expanded as one operation between tree and RTL and converted it
into four distinct operations (ADDR_EXPR, NOP_EXPR, INDIRECT_REF, and
COMPONENT_REF) and it'll be up to the RTL optimizers to put it all back
together.

I think it's taking a step backwards when we can no longer represent what
is a single expansion operation in GIMPLE as one statement.

^ permalink raw reply	[flat|nested] 61+ messages in thread
* Re: [patch] for PR 18040
@ 2004-10-18  2:35 Richard Kenner
  2004-10-18  2:51 ` Zack Weinberg
  0 siblings, 1 reply; 61+ messages in thread
From: Richard Kenner @ 2004-10-18  2:35 UTC (permalink / raw)
  To: zack; +Cc: gcc-patches

    It only makes any sense at all if I assume you meant to write 'var'
    instead of 'foo' in both places inside the body of the function.

Sort of.

    Also, you left out the declaration of uc, which meant I had to go look
    up how unchecked_conversion works.  

I wrote it at one point, but apparently edited it out.  I actually
can't write Ada very well.

      return ((r *) &var)->f1 + var[2000];

As I said earlier, that works *in this case*, but not in the general
case of nested field references, because you might be needing to take
the address of something non-addressable and ...

    This does not look very different from what you are generating now,
    but sandwiching the cast inside an address-of and dereference means
    that the gimplifier can break it down without needing to create an
    aggregate temporary, producing something like this:

But you *would* need the aggerate temporary in the nested reference case,
which is the general case.  I don't see a strong argument for doing
something special for the degenerate case here.

    The only catch is that alias analysis must understand that rp aliases
    var.  This may require some adjustment to GNAT's alias set logic.

If it did, then it couldn't be done because the types and the unchecked
conversion could be in different translation units, so you can't know
the unchecked conversion existed when you were assigning alias sets
to the types.

This stuff is *very* tricky and, as I said, we've been throught it before.

^ permalink raw reply	[flat|nested] 61+ messages in thread
* Re: [patch] for PR 18040
@ 2004-10-17 23:06 Richard Kenner
  2004-10-17 23:45 ` Zack Weinberg
  0 siblings, 1 reply; 61+ messages in thread
From: Richard Kenner @ 2004-10-17 23:06 UTC (permalink / raw)
  To: pinskia; +Cc: gcc-patches

    The way to fix this would be take the address and cast that pointer
    to the pointer of the new type.

That only works when it's addressable.  In the case of a variable it is,
but not when it's an intermediate field.

    We should never have a cast to/from a non-scaler value (except for
    maybe vectors).

We've been through all this months ago.  The addressability (alignment)
problem is the show-stopper for doing that sort of transformation in general.

^ permalink raw reply	[flat|nested] 61+ messages in thread
* Re: [patch] for PR 18040
@ 2004-10-17 22:30 Richard Kenner
  2004-10-17 22:36 ` Andrew Pinski
  2004-10-17 23:41 ` Zack Weinberg
  0 siblings, 2 replies; 61+ messages in thread
From: Richard Kenner @ 2004-10-17 22:30 UTC (permalink / raw)
  To: zack; +Cc: gcc-patches

    > ... actually, it's not good enough because it doesn't handle the
    > 	((cast) var).field
    > case and that's an expensive one.

    My gut feeling is that needing this cast means there's something wrong
    with the static type of VAR.  Could you show an example of source code
    that needs this cast, and the type tree generated for VAR?

Well, in Ada you can get it with an explicit Unchecked_Conversion to a
composite type.  For example:

	with unchecked_conversion;
	function foo return integer is
	    type arr is array (1..100_000) of integer;
	    type r is record
		f1: length;
		f2: array (1..99_999) of integer;
	    end record;

	    var: foo;
	begin
	    return uc (foo).f1 + foo (2000);
	end foo;

The type of FOO has to be an array of 100,000 integers, but the
programmer would be quite surprised if the reference to F1 involved a
400,000 byte copy!

This is, admittedly, a somewhat contrived example, but this sort of
thing occurs commonly in expanded code for different constructs.

^ permalink raw reply	[flat|nested] 61+ messages in thread
* Re: [patch] for PR 18040
@ 2004-10-17 21:24 Richard Kenner
  2004-10-17 21:43 ` Zack Weinberg
  0 siblings, 1 reply; 61+ messages in thread
From: Richard Kenner @ 2004-10-17 21:24 UTC (permalink / raw)
  To: zack; +Cc: gcc-patches

    What he's saying is that

       <COMPONENT_REF type struct field>

    (and all other reference nodes) would implicitly convert FIELD to TYPE,
    if that's not FIELD's intrinsic type.  I think this makes a hell of a
    lot of sense, personally.

... actually, it's not good enough because it doesn't handle the
	((cast) var).field
case and that's an expensive one.  If we don't have a way of representing
that, we might have to do a full copy of VAR, which might be quite large.

It's been suggested that an optimizer can remove that copy, but how could it?
There's no way of representing having the copy be removed in the tree!  Only
an RTL optimizer could remove it and that's way too low level.

^ permalink raw reply	[flat|nested] 61+ messages in thread
* Re: [patch] for PR 18040
@ 2004-10-17 21:18 Richard Kenner
  2004-10-17 21:26 ` Zack Weinberg
  0 siblings, 1 reply; 61+ messages in thread
From: Richard Kenner @ 2004-10-17 21:18 UTC (permalink / raw)
  To: zack; +Cc: gcc-patches

    What he's saying is that

       <COMPONENT_REF type struct field>

    (and all other reference nodes) would implicitly convert FIELD to TYPE,
    if that's not FIELD's intrinsic type.  I think this makes a hell of a
    lot of sense, personally.

I have no problem with that, though I suspect it's a bit of an earthquake
at this point.  Would we do it for both GENERIC and GIMPLE or just the
latter?

Note that I also think that get_inner_reference and handle_component_p
probably only need to handle VIEW_CONVERT_EXPR and not the rest of the
conversions at this point.

^ permalink raw reply	[flat|nested] 61+ messages in thread
* Re:  [patch] for PR 18040
@ 2004-10-17 21:04 Richard Kenner
  2004-10-17 21:10 ` Zack Weinberg
  0 siblings, 1 reply; 61+ messages in thread
From: Richard Kenner @ 2004-10-17 21:04 UTC (permalink / raw)
  To: dberlin; +Cc: gcc-patches

    Except that this is exactly what you are doing by making it so
    conversions can appear more or less anywhere in an expression, instead
    of just a single place.

Not "more or less anywhere", it's precisely just inside a chain of references.
Since the expander treats this as a single reference, I don't see why the
optimizers care about what's inside that except in special situations.

It *really* pessimizes the code to not allow them, plus, as I've said, it
means we can't convert all valid GENERIC to GIMPLE. 

    1. Don't allow casts except at the top level. Deal with consequences.

I'd argue exactly the other way around: having a cast at the top level
of a nest of references isn't necessary, so we can require that it be
in it's own statement. But inside is where it's useful.

    2. Make them mandatory inside component_refs, so that you *always* have
    them there.  This is what LLVM does with getelementptr. Each piece has a
    type specifier

I don't follow.  Since every tree node has a type, we always have it.
It seems that all you need is an access function that strips off the
conversion and you have the same form.

^ permalink raw reply	[flat|nested] 61+ messages in thread
* Re:  [patch] for PR 18040
@ 2004-10-17 20:25 Richard Kenner
  2004-10-17 20:47 ` Daniel Berlin
  0 siblings, 1 reply; 61+ messages in thread
From: Richard Kenner @ 2004-10-17 20:25 UTC (permalink / raw)
  To: dberlin; +Cc: gcc-patches

    It is the job of the optimizers to produce good code, not the job of
    the front end.  If the optimizers can't produce good code from this,
    then fix the optimizers.

Yeah, but there's no point in making things arbitrarily hard for them.
GIGO still applies.

^ permalink raw reply	[flat|nested] 61+ messages in thread
* Re:  [patch] for PR 18040
@ 2004-10-17 20:17 Richard Kenner
  2004-10-17 20:25 ` Daniel Berlin
  0 siblings, 1 reply; 61+ messages in thread
From: Richard Kenner @ 2004-10-17 20:17 UTC (permalink / raw)
  To: dberlin; +Cc: gcc-patches

    ((cast)var).field is not valid gimple.

    Casts must be in a statement by themselves, unless the argument is
    is_gimple_min_invariant.

The issue here is historical.  The point is to view a single nested component
reference as valid so we don't try to split it up since it can normally be
done in a single operation and spliting it up will make it more expensive.
The idea is that handled_component_p returns true for exactly those things
that will be stripped by get_inner_reference.

So we wanted to support conversions *inside* a nest of references.  In other
words, ((cast) var.field1).field2.  I thought that was specified in the
grammer; if not, it should be.

Your example above is simply a degenerate form of that and certainly needs to
be supported because otherwise we pessimize code quite badly (at best).
Suppose that cast is to a variable-size type.  Then we can't even gimplify
that expression because we can't have a variable-size temporary.  Such an
expression is certainly valid GENERIC, so saying we can't gimplify it is bad.
But if we say that it's the responsibility of the front-end to generate that
temporary, we now have horrible code: we might be copying a 1MB structure
into a temporary just to retreive one byte!

However, a side-effect of allowing this is that we allow the conversion as
the *outer* operation.  That hasn't be quite correct for a while, but
apparently never caused problems before.

So my suggestion is to modify handled_component_p to exclude a conversion at
the outer level but to have a recursive version of it that *does* allow the
conversion inside fields.  But I don't know if that addresses your issue.

^ permalink raw reply	[flat|nested] 61+ messages in thread
* Re:  [patch] for PR 18040
@ 2004-10-17 19:46 Richard Kenner
  2004-10-17 19:46 ` Daniel Berlin
  2004-10-17 19:48 ` Zdenek Dvorak
  0 siblings, 2 replies; 61+ messages in thread
From: Richard Kenner @ 2004-10-17 19:46 UTC (permalink / raw)
  To: rakdver; +Cc: gcc-patches

    is_gimple_addressable uses handled_component_p to determine whether its
    operand is a component reference.  However handled_component_p allows
    also NOP_EXPRs and CONVERT_EXPRs.  This in turn makes SRA believe that
    ((cast) var).field is valid gimple (since "(cast) var" passes
    is_gimple_addressable), which causes crash later.

Can you explain this more?  I very much think it's going in the wrong
direction to not use handled_component_p.  If we don't want to view a
an expression as being a component that's handled, we should change
handled_component_p.  But right now, what you show above in valid GIMPLE.
Perhaps there's a bug elsewehre.

^ permalink raw reply	[flat|nested] 61+ messages in thread
* [patch] for PR 18040
@ 2004-10-17 19:28 Zdenek Dvorak
  2004-10-19 21:36 ` Richard Henderson
  0 siblings, 1 reply; 61+ messages in thread
From: Zdenek Dvorak @ 2004-10-17 19:28 UTC (permalink / raw)
  To: gcc-patches

Hello,

is_gimple_addressable uses handled_component_p to determine whether its
operand is a component reference.  However handled_component_p allows
also NOP_EXPRs and CONVERT_EXPRs.  This in turn makes SRA believe that
((cast) var).field is valid gimple (since "(cast) var" passes
is_gimple_addressable), which causes crash later.

Bootstrapped & regtested on i686.

Zdenek

	PR tree-optimization/18040
	* tree-gimple.c (is_gimple_component): New function.
	(is_gimple_addressable, get_base_address): Use is_gimple_component.

Index: tree-gimple.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-gimple.c,v
retrieving revision 2.28
diff -c -3 -p -r2.28 tree-gimple.c
*** tree-gimple.c	30 Sep 2004 01:22:05 -0000	2.28
--- tree-gimple.c	17 Oct 2004 16:23:57 -0000
*************** is_gimple_condexpr (tree t)
*** 162,173 ****
    return (is_gimple_val (t) || COMPARISON_CLASS_P (t));
  }
  
  /*  Return true if T is something whose address can be taken.  */
  
  bool
  is_gimple_addressable (tree t)
  {
!   return (is_gimple_id (t) || handled_component_p (t)
  	  || TREE_CODE (t) == REALPART_EXPR
  	  || TREE_CODE (t) == IMAGPART_EXPR
  	  || INDIRECT_REF_P (t));
--- 162,192 ----
    return (is_gimple_val (t) || COMPARISON_CLASS_P (t));
  }
  
+ /* Return true if T is a gimple component reference.  */
+ 
+ static bool
+ is_gimple_component (tree t)
+ {
+   switch (TREE_CODE (t))
+     {
+     case COMPONENT_REF:
+     case ARRAY_REF:
+     case ARRAY_RANGE_REF:
+     case VIEW_CONVERT_EXPR:
+       return true;
+ 
+     default:
+       return false;;
+     }
+ }
+ 
  /*  Return true if T is something whose address can be taken.  */
  
  bool
  is_gimple_addressable (tree t)
  {
!   return (is_gimple_id (t)
! 	  || is_gimple_component (t)
  	  || TREE_CODE (t) == REALPART_EXPR
  	  || TREE_CODE (t) == IMAGPART_EXPR
  	  || INDIRECT_REF_P (t));
*************** get_call_expr_in (tree t)
*** 437,444 ****
  tree
  get_base_address (tree t)
  {
!   while (TREE_CODE (t) == REALPART_EXPR || TREE_CODE (t) == IMAGPART_EXPR
! 	 || handled_component_p (t))
      t = TREE_OPERAND (t, 0);
    
    if (SSA_VAR_P (t)
--- 456,465 ----
  tree
  get_base_address (tree t)
  {
!   while (TREE_CODE (t) == REALPART_EXPR
! 	 || TREE_CODE (t) == IMAGPART_EXPR
! 	 || TREE_CODE (t) == BIT_FIELD_REF
! 	 || is_gimple_component (t))
      t = TREE_OPERAND (t, 0);
    
    if (SSA_VAR_P (t)

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

end of thread, other threads:[~2004-10-20 13:26 UTC | newest]

Thread overview: 61+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-10-18 17:48 [patch] for PR 18040 Richard Kenner
  -- strict thread matches above, loose matches on Subject: below --
2004-10-20 13:27 Richard Kenner
2004-10-20  0:25 Richard Kenner
2004-10-19 23:26 Richard Kenner
2004-10-19 23:22 Richard Kenner
2004-10-19 23:03 Richard Kenner
2004-10-19 23:13 ` Jason Merrill
2004-10-19 22:48 Richard Kenner
2004-10-19 23:01 ` Jason Merrill
2004-10-19 23:07 ` Zack Weinberg
2004-10-18 15:42 Richard Kenner
2004-10-18 14:52 Richard Kenner
2004-10-18 15:20 ` Daniel Berlin
2004-10-18 14:38 Richard Kenner
2004-10-18 14:24 Richard Kenner
2004-10-19 22:50 ` Zack Weinberg
2004-10-18 14:22 Richard Kenner
2004-10-19 22:47 ` Zack Weinberg
2004-10-18  3:12 Richard Kenner
2004-10-18  4:02 ` Zack Weinberg
2004-10-18  4:26   ` Daniel Berlin
2004-10-18  2:46 Richard Kenner
2004-10-18  2:38 Richard Kenner
2004-10-18  3:14 ` Zack Weinberg
2004-10-18  2:35 Richard Kenner
2004-10-18  2:51 ` Zack Weinberg
2004-10-17 23:06 Richard Kenner
2004-10-17 23:45 ` Zack Weinberg
2004-10-18  0:23   ` Zack Weinberg
2004-10-17 22:30 Richard Kenner
2004-10-17 22:36 ` Andrew Pinski
2004-10-17 23:41 ` Zack Weinberg
2004-10-18 13:13   ` Florian Weimer
2004-10-18 17:24     ` Jason Merrill
2004-10-18 17:37       ` Florian Weimer
2004-10-18 18:02         ` Jason Merrill
2004-10-19 22:40     ` Zack Weinberg
2004-10-17 21:24 Richard Kenner
2004-10-17 21:43 ` Zack Weinberg
2004-10-17 21:18 Richard Kenner
2004-10-17 21:26 ` Zack Weinberg
2004-10-17 21:04 Richard Kenner
2004-10-17 21:10 ` Zack Weinberg
2004-10-19 21:36   ` Richard Henderson
2004-10-19 22:19     ` Daniel Berlin
2004-10-20  7:03       ` Jason Merrill
2004-10-19 22:51     ` Zack Weinberg
2004-10-20  0:02       ` Richard Henderson
2004-10-17 20:25 Richard Kenner
2004-10-17 20:47 ` Daniel Berlin
2004-10-17 20:17 Richard Kenner
2004-10-17 20:25 ` Daniel Berlin
2004-10-17 19:46 Richard Kenner
2004-10-17 19:46 ` Daniel Berlin
2004-10-17 19:48 ` Zdenek Dvorak
2004-10-17 20:01   ` Daniel Berlin
2004-10-17 19:28 Zdenek Dvorak
2004-10-19 21:36 ` Richard Henderson
2004-10-19 22:03   ` Zdenek Dvorak
2004-10-19 22:04     ` Andrew Pinski
2004-10-19 22:06       ` Zdenek Dvorak

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).