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