On Fri, Jun 1, 2012 at 2:02 AM, Martin Jambor <mjam...@suse.cz> wrote: > Hi, > > this patch adds the capability to build aggregate jump functions. > These consist of: > > 1) information what known compile time IPA-invariants are at various > offsets of an aggregate passed to a callee either by reference > (when the parameter is pointer) or by value (when it is an > aggregate). This patch simply scans the current BB backwards from > the call statement and examines what values are stored there. Even > this simple approach does not look particularly simple > (determine_known_aggregate_parts), it is however usually sufficient > for Fortran array descriptions (in the testcases I have seen). For > more advanced uses like devirtualization we'll need something that > will examine the whole function but will look quite like this, only > even more messy, I'm afraid. > > When we do this, we also record the type through which data was > stored into the aggregate, which is either the type of a DECL or > type stored in the offset of a MEM_REF. > > 2) Being able to conservatively but usefully recognize that an > aggregate (passed either by reference or a value) that we got from > a caller and pass it to a callee has not changed. > > This is slightly complex in cases where aggregates are passed by > reference. Because in gimple pointer types carry more-or-less no > information about the data it points to, we'd normally have to feed > AA with a type that aliases all in order to get conservatively > correct results. That might however be too much conservative. We > circumvent this problem by feeding AA the pointed-to type but also > verifying that the aggregate data was stored with the same type (or > a type containing the pointed-to type at the expected offset). > > The data structures can also represent such pass-through functions > with known listed exceptions but that is not currently implemented > and is left for later. > > However, this patch does not use the collected data in any way, that > is what two subsequent patches do. > > The patch passes bootstrap and testing on x86_64-linux.
Quite a large patch ... let's iterate a bit about the aliasing stuff. If I understand correctly you have ... foo (struct X *p) { .... (1) bar (p); } and want to know whether *p was modified before the call to bar so you can pass thru the jump function (you are not interested to modify the jump function, clearing clobbered information yet?). Now I don't understand on how you might be able to ever use type-based alias info to disambiguate any may-defs of *p. Can you explain why you believe you can do so? I understand you possibly want to verify whether a consumer of *p can eventually be replaced by the jump function value, thus the value is of matching type, but would that be not only applicable at transform time? Given that you'd always be able to fallback to 'const' typeof (*p) tem = <jump function>; ... = properly-typed-read-from-tem-with-alias-set-zero; and leave constant propagation to the optimizers? At least I think you confuse what "type" you can use at value-replacement time with the "type" you use for determining whether *p is invalidated. > static void > -compute_cst_member_ptr_arguments (struct ipa_edge_args *args, > - gimple call) > +init_ao_ref_for_byref_agg_jf (ao_ref *r, tree base, tree type) > +{ > + static tree alias_all_type = NULL; > + > + if (!alias_all_type) > + alias_all_type = build_pointer_type_for_mode (char_type_node, > + ptr_mode, true); > + ao_ref_init (r, build2 (MEM_REF, type, base, > + build_int_cst (alias_all_type, 0))); > +} this won't survive garbage collection I believe. I think you can more easily use ao_ref_init_from_ptr_and_size here: ao_ref_init_from_ptr_and_size (r, base, TYPE_SIZE_UNIT (TREE_TYPE (base))); that makes sure to use alias-set zero. As you've seen in the recent bugreport the alias stmt walking can be quite a compile-time hog so you should eventually limit yourself conservatively by using the number of stmts walked returned by walk_aliased_vdefs. Richard.