]> gcc.gnu.org Git - gcc.git/commitdiff
cgraph.c (cgraph_create_indirect_edge): Discover polymorphic calls and record basic...
authorJan Hubicka <jh@suse.cz>
Sun, 18 Aug 2013 09:22:42 +0000 (11:22 +0200)
committerJan Hubicka <hubicka@gcc.gnu.org>
Sun, 18 Aug 2013 09:22:42 +0000 (09:22 +0000)
* cgraph.c (cgraph_create_indirect_edge): Discover
polymorphic calls and record basic info into indirect_info.
* gimple-fold.c (gimple_fold_call): When doing BINFO based
devirtualization, ignore objc function calls.
* ipa-cp.c (initialize_node_lattices): Be ready for polymorphic
call with no parm index info.
* ipa-prop.c (ipa_analyze_call_uses): Likewise.
* tree.c (virtual_method_call_p): New function.
* tree.h (virtual_method_call_p): Declare.

From-SVN: r201824

gcc/ChangeLog
gcc/cgraph.c
gcc/gimple-fold.c
gcc/ipa-cp.c
gcc/ipa-prop.c
gcc/tree.c
gcc/tree.h

index 6462a0559be5636c0ee2a190777f7fd80ad82f09..faa465ab27ff0a4b0da489876772fe5aebbfe662 100644 (file)
@@ -1,3 +1,15 @@
+2013-08-18  Jan Hubicka  <jh@suse.cz>
+
+       * cgraph.c (cgraph_create_indirect_edge): Discover
+       polymorphic calls and record basic info into indirect_info.
+       * gimple-fold.c (gimple_fold_call): When doing BINFO based
+       devirtualization, ignore objc function calls.
+       * ipa-cp.c (initialize_node_lattices): Be ready for polymorphic
+       call with no parm index info.
+       * ipa-prop.c (ipa_analyze_call_uses): Likewise.
+       * tree.c (virtual_method_call_p): New function.
+       * tree.h (virtual_method_call_p): Declare.
+
 2013-08-16  Jan Hubicka  <jh@suse.cz>
 
        PR middle-end/58179
index a939ae834848571941c3160c50292ae36e99afaf..e2f96d6436d3956990a3f61feec868cb48e74514 100644 (file)
@@ -925,6 +925,7 @@ cgraph_create_indirect_edge (struct cgraph_node *caller, gimple call_stmt,
 {
   struct cgraph_edge *edge = cgraph_create_edge_1 (caller, NULL, call_stmt,
                                                   count, freq);
+  tree target;
 
   edge->indirect_unknown_callee = 1;
   initialize_inline_failed (edge);
@@ -932,6 +933,23 @@ cgraph_create_indirect_edge (struct cgraph_node *caller, gimple call_stmt,
   edge->indirect_info = cgraph_allocate_init_indirect_info ();
   edge->indirect_info->ecf_flags = ecf_flags;
 
+  /* Record polymorphic call info.  */
+  if (call_stmt
+      && (target = gimple_call_fn (call_stmt))
+      && virtual_method_call_p (target))
+    {
+      tree type = obj_type_ref_class (target);
+
+
+      /* Only record types can have virtual calls.  */
+      gcc_assert (TREE_CODE (type) == RECORD_TYPE);
+      edge->indirect_info->param_index = -1;
+      edge->indirect_info->otr_token
+        = tree_low_cst (OBJ_TYPE_REF_TOKEN (target), 1);
+      edge->indirect_info->otr_type = type;
+      edge->indirect_info->polymorphic = 1;
+    }
+
   edge->next_callee = caller->indirect_calls;
   if (caller->indirect_calls)
     caller->indirect_calls->prev_callee = edge;
index e9cd9aa2292d9002b8dc2f3dff2c497ba462621e..df6aef534eb41489eedfcf6c3a1e90e5de9a4679 100644 (file)
@@ -1105,7 +1105,7 @@ gimple_fold_call (gimple_stmt_iterator *gsi, bool inplace)
          gimple_call_set_fn (stmt, OBJ_TYPE_REF_EXPR (callee));
          changed = true;
        }
-      else
+      else if (virtual_method_call_p (callee))
        {
          tree obj = OBJ_TYPE_REF_OBJECT (callee);
          tree binfo = gimple_extract_devirt_binfo_from_cst
index 312672cc49f0425d998639eeb745cd36fa1a4e22..93934e20de827ba675e25831d12dd753d16c6aa2 100644 (file)
@@ -734,7 +734,8 @@ initialize_node_lattices (struct cgraph_node *node)
     }
 
   for (ie = node->indirect_calls; ie; ie = ie->next_callee)
-    if (ie->indirect_info->polymorphic)
+    if (ie->indirect_info->polymorphic
+        && ie->indirect_info->param_index >= 0)
       {
        gcc_checking_assert (ie->indirect_info->param_index >= 0);
        ipa_get_parm_lattices (info,
index 7cda34637b23ba59ed975c04b398db8224d9ef2d..7ffa929c4111342c0b7e2858527fa863dd8fa331 100644 (file)
@@ -1922,7 +1922,7 @@ ipa_analyze_call_uses (struct cgraph_node *node,
     return;
   if (TREE_CODE (target) == SSA_NAME)
     ipa_analyze_indirect_call_uses (node, info, parms_ainfo, call, target);
-  else if (TREE_CODE (target) == OBJ_TYPE_REF)
+  else if (virtual_method_call_p (target))
     ipa_analyze_virtual_call_uses (node, info, call, target);
 }
 
index 8b4d86585bbd6cb1287990746d40cc9528435e7e..9d4bc7f9fc8a3ee69d755140fc9367818cbcadad 100644 (file)
@@ -11864,6 +11864,27 @@ types_same_for_odr (tree type1, tree type2)
   return true;
 }
 
+/* TARGET is a call target of GIMPLE call statement
+   (obtained by gimple_call_fn).  Return true if it is
+   OBJ_TYPE_REF representing an virtual call of C++ method.
+   (As opposed to OBJ_TYPE_REF representing objc calls
+   through a cast where middle-end devirtualization machinery
+   can't apply.) */
+
+bool
+virtual_method_call_p (tree target)
+{
+  if (TREE_CODE (target) != OBJ_TYPE_REF)
+    return false;
+  target = TREE_TYPE (target);
+  gcc_checking_assert (TREE_CODE (target) == POINTER_TYPE);
+  target = TREE_TYPE (target);
+  if (TREE_CODE (target) == FUNCTION_TYPE)
+    return false;
+  gcc_checking_assert (TREE_CODE (target) == METHOD_TYPE);
+  return true;
+}
+
 /* REF is OBJ_TYPE_REF, return the class the ref corresponds to.  */
 
 tree
index c1d8d57e8d543dd721fee9be265395420aec0050..4dbff212b97b3bce367f6ca7f6780bc34a5035e5 100644 (file)
@@ -5974,6 +5974,7 @@ extern location_t tree_nonartificial_location (tree);
 extern tree block_ultimate_origin (const_tree);
 
 extern tree get_binfo_at_offset (tree, HOST_WIDE_INT, tree);
+extern bool virtual_method_call_p (tree);
 extern tree obj_type_ref_class (tree ref);
 extern bool types_same_for_odr (tree type1, tree type2);
 extern tree get_ref_base_and_extent (tree, HOST_WIDE_INT *,
This page took 0.101765 seconds and 5 git commands to generate.