The jump function logic for regular callback edges does not apply to
internal callback edges, as it relies on the existence of a
callback-carrying edge for the remapping.  In order to make ipa-cp act
on assume bodies, we need to remap the arguments before the analysis is
done.  This patch adds the remapping logic and also adds an early return
to ipa_polymorphic_call_context::get_dynamic_type, which tries to get
the called function from the call statement with gimple_call_fn.
This of course doesn't work for internal calls.

gcc/ChangeLog:

        * ipa-polymorphic-call.cc
        (ipa_polymorphic_call_context::get_dynamic_type): Exclude
        IFN_ASSUME internal calls.
        * ipa-prop.cc
        (ipa_compute_jump_functions_for_edge): Remap arguments for
        callback edges.

Signed-off-by: Josef Melcr <[email protected]>
---
 gcc/ipa-polymorphic-call.cc |  7 +++++++
 gcc/ipa-prop.cc             | 14 ++++++++++++--
 2 files changed, 19 insertions(+), 2 deletions(-)

diff --git a/gcc/ipa-polymorphic-call.cc b/gcc/ipa-polymorphic-call.cc
index addb52561c7..12d9c9f878a 100644
--- a/gcc/ipa-polymorphic-call.cc
+++ b/gcc/ipa-polymorphic-call.cc
@@ -41,6 +41,8 @@ along with GCC; see the file COPYING3.  If not see
 #include "alloc-pool.h"
 #include "symbol-summary.h"
 #include "symtab-thunks.h"
+#include "attr-callback.h"
+#include "callback-info.h"
 
 /* Return true when TYPE contains an polymorphic type and thus is interesting
    for devirtualization machinery.  */
@@ -1584,6 +1586,11 @@ ipa_polymorphic_call_context::get_dynamic_type (tree 
instance,
   if (!instance)
     return false;
 
+  /* Bail to avoid segfaults for IFN_ASSUME internal calls.  They are not
+     polymorphic anyway.  */
+  if (callback_ifn_assume_call_p (call))
+    return false;
+
   if (otr_type)
     otr_type = TYPE_MAIN_VARIANT (otr_type);
 
diff --git a/gcc/ipa-prop.cc b/gcc/ipa-prop.cc
index 3f9f45b02c8..bc31e8e3399 100644
--- a/gcc/ipa-prop.cc
+++ b/gcc/ipa-prop.cc
@@ -2492,7 +2492,8 @@ ipa_compute_jump_functions_for_edge (struct 
ipa_func_body_info *fbi,
   ipa_node_params *info = ipa_node_params_sum->get (cs->caller);
   ipa_edge_args *args = ipa_edge_args_sum->get_create (cs);
   gcall *call = cs->call_stmt;
-  int n, arg_num = gimple_call_num_args (call);
+  callback_info *ci = callback_info_sum->get (cs);
+  int n, arg_num = callback_call_num_args_summary (call, ci);
   bool useful_context = false;
 
   if (arg_num == 0 || args->jump_functions)
@@ -2508,7 +2509,16 @@ ipa_compute_jump_functions_for_edge (struct 
ipa_func_body_info *fbi,
   for (n = 0; n < arg_num; n++)
     {
       struct ipa_jump_func *jfunc = ipa_get_ith_jump_func (args, n);
-      tree arg = gimple_call_arg (call, n);
+      tree arg;
+      if (cs->callback)
+       {
+         int remapped_idx = ci->arg_mapping[n];
+         if (remapped_idx == ARG_MAPPING_UNKNOWN_IDX)
+           continue;
+         arg = gimple_call_arg (call, remapped_idx);
+       }
+      else
+       arg = gimple_call_arg (call, n);
       tree param_type = ipa_get_callee_param_type (cs, n);
       if (flag_devirtualize && POINTER_TYPE_P (TREE_TYPE (arg)))
        {
-- 
2.55.0

Reply via email to