Hi,

On Thu, 3 Nov 2011, Richard Guenther wrote:

> > +  /* Add clobbers for all variables that go out of scope.  */
> > +  for (t = BIND_EXPR_VARS (bind_expr); t ; t = DECL_CHAIN (t))
> > +    {
> > +      if (TREE_CODE (t) == VAR_DECL
> > +         && !is_global_var (t)
> 
> I think you want to use auto_var_in_fn () here.

I don't think so.  It accepts LABEL_DECLs (and others, though I'm only 
interested in VAR_DECLs here), and barring the check on DECL_CONTEXT 
(which I don't need) it's exactly equivalent to !is_global_var.

> > +         && !DECL_HARD_REGISTER (t)
> > +         && !TREE_THIS_VOLATILE (t)
> 
> Any reason for that?

We must not introduce new writes (which the clobbers are) to 
volatile storage.  And HARD_REGs obviously never will be placed on the 
stack.

> > +         && !DECL_HAS_VALUE_EXPR_P (t)
> > +         /* Only care for variables that have to be in memory.  Others
> > +            will be rewritten into SSA names, hence moved to the 
> > top-level.  */
> > +         && needs_to_live_in_memory (t))
> 
> Looking at the predicate this will exclude non-address-taken aggregates. 
> We talked about this as an optimization, but that would need a real 
> computation of a life problem for those.

Hmm?  The whole thing would work exactly the same for address-taken and 
non-address-taken aggregates.

> Thus, does this mean that non-address-taken aggregates won't get their 
> stack slots shared right now?

Correct.  I considered them unimportant enough to not deserve the special 
treatment.  There aren't many things you can do with non-address-taken 
aggregates that SRA wouldn't decompose.

> > +  if (!decl_to_stack_part)
> > +    decl_to_stack_part = pointer_map_create ();
> > +
> >   v = &stack_vars[stack_vars_num];
> > +  * (size_t *)pointer_map_insert (decl_to_stack_part, decl) = 
> > stack_vars_num;
> 
> Use uintptr_t.

Oh?  Since when can we use that?  It's used nowhere else in GCC.

> > +         if (gimple_assign_single_p (stmt)
> > +             && TREE_CLOBBER_P (gimple_assign_rhs1 (stmt)))
> 
> Can you introduce a gimple_clobber_p (stmt) predicate for this?

Yes.

> (not sure if I like "clobber" too much, that sounds like a may-kill
> while this should have the semantic of a true kill operation, thus,
> maybe change s/clobber/kill/ throughout the patch?)

Ah, bikeshedding :) A clobber is indeed a may-kill.  The indeterminate 
value stored into it may as well be the original content (without that 
it's a must-kill).  Like for a kill, which also seems to imply an 
indeterminate value.  From that perspective also a kill is a may-kill, or 
IOW "clobber" and "kill" are equivalent.  I don't like the notion of 
"killing" variables or storage, they remain in existence, just the 
contents aren't, I really prefer clobber.

> > Index: tree-ssa-sccvn.c
> > ===================================================================
> > --- tree-ssa-sccvn.c.orig       2011-11-02 21:18:45.000000000 +0100
> > +++ tree-ssa-sccvn.c    2011-11-02 21:19:51.000000000 +0100
> > @@ -1422,6 +1422,7 @@ vn_reference_lookup_3 (ao_ref *ref, tree
> >   else if (is_gimple_reg_type (vr->type)
> >           && gimple_assign_single_p (def_stmt)
> >           && gimple_assign_rhs_code (def_stmt) == CONSTRUCTOR
> > +          && !TREE_CLOBBER_P (gimple_assign_rhs1 (def_stmt))
> 
> Does that really matter?  We can as well assume zeros for the new content.

No, we cannot.  If we assume so then a second store also storing zeros 
into it might be removed because it's "already filled with zeros", where 
at runtime this doesn't hold and the second store would have been 
significant:

for (i<N) { aggr.i=0; use(&aggr); aggr <= clobber }
-->
aggr.i=0; for (i<N) { use(&aggr); aggr <= clobber }


Ciao,
Michael.

Reply via email to