diff mbox

Fix PR66705

Message ID alpine.LSU.2.11.1509021545020.5523@zhemvz.fhfr.qr
State New
Headers show

Commit Message

Richard Biener Sept. 2, 2015, 1:45 p.m. UTC
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.

Richard.

2015-09-02  Richard Biener  <rguenther@suse.de>

	PR ipa/66705
	* tree-ssa-structalias.c (ctor_for_analysis): New function.
	(create_variable_info_for_1): Use ctor_for_analysis instead
	of get_constructor.
	(create_variable_info_for): Likewise.

	* g++.dg/lto/pr66705_0.C: New testcase.

Comments

Jan Hubicka Sept. 2, 2015, 2:23 p.m. UTC | #1
> 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
Richard Biener Sept. 2, 2015, 2:31 p.m. UTC | #2
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.
Jan Hubicka Sept. 3, 2015, 8:50 a.m. UTC | #3
> > 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.
diff mbox

Patch

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;)
+      ;
+}