PR tree-optimization/60899
authorhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 21 May 2014 06:16:03 +0000 (06:16 +0000)
committerhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 21 May 2014 06:16:03 +0000 (06:16 +0000)
* gimple-fold.c (can_refer_decl_in_current_unit_p): Cleanup;
assume all static symbols will have definition wile parsing and
check the do have definition later in compilation; check that
variable referring symbol will be output before concluding that
reference is safe; be conservative for referring local statics;
be more precise about when comdat is output in other partition.

g++.dg/ipa/devirt-11.C: Update template.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@210676 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/gimple-fold.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/ipa/devirt-11.C

index 104c87d..fe3e7ec 100644 (file)
@@ -1,5 +1,15 @@
 2014-05-20  Jan Hubicka  <hubicka@ucw.cz>
 
+       PR tree-optimization/60899
+       * gimple-fold.c (can_refer_decl_in_current_unit_p): Cleanup;
+       assume all static symbols will have definition wile parsing and
+       check the do have definition later in compilation; check that
+       variable referring symbol will be output before concluding that
+       reference is safe; be conservative for referring local statics;
+       be more precise about when comdat is output in other partition.
+
+2014-05-20  Jan Hubicka  <hubicka@ucw.cz>
+
        PR bootstrap/60984
        * ipa-inline-transform.c (inline_call): Use add CALLEE_REMOVED parameter.
        * ipa-inline.c (inline_to_all_callers): If callee was removed; return.
index 1c2eed5..44bb0e2 100644 (file)
@@ -94,8 +94,12 @@ can_refer_decl_in_current_unit_p (tree decl, tree from_decl)
   /* Static objects can be referred only if they was not optimized out yet.  */
   if (!TREE_PUBLIC (decl) && !DECL_EXTERNAL (decl))
     {
+      /* Before we start optimizing unreachable code we can be sure all
+        static objects are defined.  */
+      if (cgraph_function_flags_ready)
+       return true;
       snode = symtab_get_node (decl);
-      if (!snode)
+      if (!snode || !snode->definition)
        return false;
       node = dyn_cast <cgraph_node *> (snode);
       return !node || !node->global.inlined_to;
@@ -103,10 +107,12 @@ can_refer_decl_in_current_unit_p (tree decl, tree from_decl)
 
   /* We will later output the initializer, so we can refer to it.
      So we are concerned only when DECL comes from initializer of
-     external var.  */
+     external var or var that has been optimized out.  */
   if (!from_decl
       || TREE_CODE (from_decl) != VAR_DECL
-      || !DECL_EXTERNAL (from_decl)
+      || (!DECL_EXTERNAL (from_decl)
+         && (vnode = varpool_get_node (from_decl)) != NULL
+         && vnode->definition)
       || (flag_ltrans
          && symtab_get_node (from_decl)->in_other_partition))
     return true;
@@ -123,9 +129,9 @@ can_refer_decl_in_current_unit_p (tree decl, tree from_decl)
      reference imply need to include function body in the curren tunit.  */
   if (TREE_PUBLIC (decl) && !DECL_COMDAT (decl))
     return true;
-  /* We are not at ltrans stage; so don't worry about WHOPR.
-     Also when still gimplifying all referred comdat functions will be
-     produced.
+  /* We have COMDAT.  We are going to check if we still have definition
+     or if the definition is going to be output in other partition.
+     Bypass this when gimplifying; all needed functions will be produced.
 
      As observed in PR20991 for already optimized out comdat virtual functions
      it may be tempting to not necessarily give up because the copy will be
@@ -134,35 +140,17 @@ can_refer_decl_in_current_unit_p (tree decl, tree from_decl)
      units where they are used and when the other unit was compiled with LTO
      it is possible that vtable was kept public while the function itself
      was privatized. */
-  if (!flag_ltrans && (!DECL_COMDAT (decl) || !cgraph_function_flags_ready))
+  if (!cgraph_function_flags_ready)
     return true;
 
-  /* OK we are seeing either COMDAT or static variable.  In this case we must
-     check that the definition is still around so we can refer it.  */
-  if (TREE_CODE (decl) == FUNCTION_DECL)
-    {
-      node = cgraph_get_node (decl);
-      /* Check that we still have function body and that we didn't took
-         the decision to eliminate offline copy of the function yet.
-         The second is important when devirtualization happens during final
-         compilation stage when making a new reference no longer makes callee
-         to be compiled.  */
-      if (!node || !node->definition || node->global.inlined_to)
-       {
-         gcc_checking_assert (!TREE_ASM_WRITTEN (decl));
-         return false;
-       }
-    }
-  else if (TREE_CODE (decl) == VAR_DECL)
-    {
-      vnode = varpool_get_node (decl);
-      if (!vnode || !vnode->definition)
-       {
-         gcc_checking_assert (!TREE_ASM_WRITTEN (decl));
-         return false;
-       }
-    }
-  return true;
+  snode = symtab_get_node (decl);
+  if (!snode
+      || ((!snode->definition || DECL_EXTERNAL (decl))
+         && (!snode->in_other_partition
+             || (!snode->forced_by_abi && !snode->force_output))))
+    return false;
+  node = dyn_cast <cgraph_node *> (snode);
+  return !node || !node->global.inlined_to;
 }
 
 /* CVAL is value taken from DECL_INITIAL of variable.  Try to transform it into
index 142c9fa..117c65f 100644 (file)
@@ -1,3 +1,8 @@
+2014-05-20  Jan Hubicka  <hubicka@ucw.cz>
+
+       PR tree-optimization/60899
+       g++.dg/ipa/devirt-11.C: Update template.
+
 2014-05-20  Edward Smith-Rowland  <3dw4rd@verizon.net>
 
        PR C++/61038
index d30d56c..3246e21 100644 (file)
@@ -42,8 +42,7 @@ bar ()
   baz ();
   c + d;
 }
-/* While inlining function called once we should devirtualize a new call to fn2
-   and two to fn3. While doing so the new symbol for fn2 needs to be
-   introduced.  */
-/* { dg-final { scan-ipa-dump-times "Discovered a virtual call to a known target" 3 "inline"  } } */
+/* While inlining function called once we should devirtualize a new call to fn3.
+   Because fn2 is already removed, we should not devirtualize.  */
+/* { dg-final { scan-ipa-dump-times "Discovered a virtual call to a known target" 1 "inline"  } } */
 /* { dg-final { cleanup-ipa-dump "inline" } } */