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.