Message ID | alpine.LSU.2.11.1509021545020.5523@zhemvz.fhfr.qr |
---|---|
State | New |
Headers | show |
> On Wed, 2 Sep 2015, Richard Biener wrote: > > > On Wed, 2 Sep 2015, Jan Hubicka wrote: > > > > > > > > > > I was naiively using ->get_constructor in IPA PTA without proper > > > > checking on wheter that succeeds. Now I tried to use ctor_for_folding > > > > but that isn't good as we want to analyze non-const globals in IPA > > > > PTA and we need to analyze their initialiers as well. > > > > > > > > Thus I'm trying below with ctor_for_analysis, but I really "just" > > > > need the initializer or a "not available" for conservative handling. > > > > > > > > Bootstrapped and tested on x86_64-unknown-linux-gnu. > > > > > > > > Honza - I suppose you should doble-check this and suggest sth > > > > different (or implement sth more generic in the IPA infrastructure). > > > > > > Yep, you are correct that we don't currently have way to look into ctor > > > without actually loading. But do you need something more than just walking > > > references that you already have in ipa-ref lists? > > > > Hmm, no, ipa-ref list should be enough (unless we start field-sensitive > > analysis or need NULL inits for correctness). Still have to figure out > > how to walk the list and how the reference would look like (what > > is ref->use? IPA_REF_ADDR? can those be speculative?) > > Sth like the following seems to work. Yep, it looks good to me. Do you conservatively handle constructors that are in other units? Those won't have ipa-ref lists streamed to ltrans stage. I suppose you do not care because all references in them can be supplied by foreign code, so you need to be conservative anyway. Honza
On Wed, 2 Sep 2015, Jan Hubicka wrote: > > On Wed, 2 Sep 2015, Richard Biener wrote: > > > > > On Wed, 2 Sep 2015, Jan Hubicka wrote: > > > > > > > > > > > > > I was naiively using ->get_constructor in IPA PTA without proper > > > > > checking on wheter that succeeds. Now I tried to use ctor_for_folding > > > > > but that isn't good as we want to analyze non-const globals in IPA > > > > > PTA and we need to analyze their initialiers as well. > > > > > > > > > > Thus I'm trying below with ctor_for_analysis, but I really "just" > > > > > need the initializer or a "not available" for conservative handling. > > > > > > > > > > Bootstrapped and tested on x86_64-unknown-linux-gnu. > > > > > > > > > > Honza - I suppose you should doble-check this and suggest sth > > > > > different (or implement sth more generic in the IPA infrastructure). > > > > > > > > Yep, you are correct that we don't currently have way to look into ctor > > > > without actually loading. But do you need something more than just walking > > > > references that you already have in ipa-ref lists? > > > > > > Hmm, no, ipa-ref list should be enough (unless we start field-sensitive > > > analysis or need NULL inits for correctness). Still have to figure out > > > how to walk the list and how the reference would look like (what > > > is ref->use? IPA_REF_ADDR? can those be speculative?) > > > > Sth like the following seems to work. > > Yep, it looks good to me. Do you conservatively handle constructors that > are in other units? Those won't have ipa-ref lists streamed to ltrans > stage. I suppose you do not care because all references in them can be > supplied by foreign code, so you need to be conservative anyway. I use all_refs_explicit_p () to go a conservative path. And indeed I may trip aliases (well, the code doesn't handle aliases correctly anyway I guess - I just walk vars via /* Create constraints for global variables and their initializers. */ FOR_EACH_VARIABLE (var) { if (var->alias && var->analyzed) continue; get_vi_for_tree (var->decl); } and in get_vi_for_tree look at its ref list. So I should only get "ultimate" alias targets and only those may have initializers? Richard.
> > supplied by foreign code, so you need to be conservative anyway. > > I use all_refs_explicit_p () to go a conservative path. And indeed Yep, that should be safe. I guess you want two things 1) discover any possible ADDR_REF of a given symbol with all_refs_explicit_p. For that you want walk referring list of the symbol or if you go forward direction walk all initializers of all non-aliases you can see as all of them may possibly reffer to it. 2) discover what static variables you have fully in control and know all references to. I suppose that is where you use all_refs_explicit_p Explicit reference may be also an alias that may be exported. all_refs_explicit_p cares about symbol, not about the initializer itself, so you may want to have a version of this predicate that walks all aliases and checks that all of them have all refs explicit. > I may trip aliases (well, the code doesn't handle aliases correctly > anyway I guess - I just walk vars via > > /* Create constraints for global variables and their initializers. */ > FOR_EACH_VARIABLE (var) > { > if (var->alias && var->analyzed) > continue; > > get_vi_for_tree (var->decl); > } > > and in get_vi_for_tree look at its ref list. So I should only get > "ultimate" alias targets and only those may have initializers? Yep, only ulitmate alias targets have initializers. Honza > > Richard.
Index: gcc/tree-ssa-structalias.c =================================================================== --- gcc/tree-ssa-structalias.c (revision 227207) +++ gcc/tree-ssa-structalias.c (working copy) @@ -5650,7 +5650,6 @@ create_variable_info_for_1 (tree decl, c auto_vec<fieldoff_s> fieldstack; fieldoff_s *fo; unsigned int i; - varpool_node *vnode; if (!declsize || !tree_fits_uhwi_p (declsize)) @@ -5668,12 +5667,10 @@ create_variable_info_for_1 (tree decl, c /* Collect field information. */ if (use_field_sensitive && var_can_have_subvars (decl) - /* ??? Force us to not use subfields for global initializers - in IPA mode. Else we'd have to parse arbitrary initializers. */ + /* ??? Force us to not use subfields for globals in IPA mode. + Else we'd have to parse arbitrary initializers. */ && !(in_ipa_mode - && is_global_var (decl) - && (vnode = varpool_node::get (decl)) - && vnode->get_constructor ())) + && is_global_var (decl))) { fieldoff_s *fo = NULL; bool notokay = false; @@ -5805,13 +5802,13 @@ create_variable_info_for (tree decl, con /* If this is a global variable with an initializer and we are in IPA mode generate constraints for it. */ - if (vnode->get_constructor () - && vnode->definition) + ipa_ref *ref; + for (unsigned idx = 0; vnode->iterate_reference (idx, ref); ++idx) { auto_vec<ce_s> rhsc; struct constraint_expr lhs, *rhsp; unsigned i; - get_constraint_for_rhs (vnode->get_constructor (), &rhsc); + get_constraint_for_address_of (ref->referred->decl, &rhsc); lhs.var = vi->id; lhs.offset = 0; lhs.type = SCALAR; Index: gcc/testsuite/g++.dg/lto/pr66705_0.C =================================================================== --- gcc/testsuite/g++.dg/lto/pr66705_0.C (revision 0) +++ gcc/testsuite/g++.dg/lto/pr66705_0.C (working copy) @@ -0,0 +1,15 @@ +// { dg-lto-do link } +// { dg-lto-options { { -O2 -flto -flto-partition=max -fipa-pta } } } +// { dg-extra-ld-options "-r -nostdlib" } + +class A { +public: + A(); +}; +int a = 0; +void foo() { + a = 0; + A b; + for (; a;) + ; +}