diff options
Diffstat (limited to 'gcc-4.9/gcc/ipa-prop.c')
-rw-r--r-- | gcc-4.9/gcc/ipa-prop.c | 78 |
1 files changed, 55 insertions, 23 deletions
diff --git a/gcc-4.9/gcc/ipa-prop.c b/gcc-4.9/gcc/ipa-prop.c index 9f144fa34..2ccbbdbca 100644 --- a/gcc-4.9/gcc/ipa-prop.c +++ b/gcc-4.9/gcc/ipa-prop.c @@ -56,6 +56,7 @@ along with GCC; see the file COPYING3. If not see #include "data-streamer.h" #include "tree-streamer.h" #include "params.h" +#include "l-ipo.h" #include "ipa-utils.h" #include "stringpool.h" #include "tree-ssanames.h" @@ -1618,7 +1619,20 @@ ipa_compute_jump_functions_for_edge (struct param_analysis_info *parms_ainfo, tree param_type = ipa_get_callee_param_type (cs, n); if (is_gimple_ip_invariant (arg)) - ipa_set_jf_constant (jfunc, arg, cs); + { + if (L_IPO_COMP_MODE && TREE_CODE (arg) == ADDR_EXPR + && TREE_CODE (TREE_OPERAND (arg, 0)) == FUNCTION_DECL) + { + tree fdecl = TREE_OPERAND (arg, 0); + tree real_fdecl = cgraph_lipo_get_resolved_node (fdecl)->decl; + if (fdecl != real_fdecl) + { + arg = unshare_expr (arg); + TREE_OPERAND (arg, 0) = real_fdecl; + } + } + ipa_set_jf_constant (jfunc, arg, cs); + } else if (!is_gimple_reg_type (TREE_TYPE (arg)) && TREE_CODE (arg) == PARM_DECL) { @@ -2701,6 +2715,29 @@ try_make_edge_direct_simple_call (struct cgraph_edge *ie, return cs; } +/* Return the target to be used in cases of impossible devirtualization. IE + and target (the latter can be NULL) are dumped when dumping is enabled. */ + +tree +ipa_impossible_devirt_target (struct cgraph_edge *ie, tree target) +{ + if (dump_file) + { + if (target) + fprintf (dump_file, + "Type inconsistent devirtualization: %s/%i->%s\n", + ie->caller->name (), ie->caller->order, + IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (target))); + else + fprintf (dump_file, + "No devirtualization target in %s/%i\n", + ie->caller->name (), ie->caller->order); + } + tree new_target = builtin_decl_implicit (BUILT_IN_UNREACHABLE); + cgraph_get_create_node (new_target); + return new_target; +} + /* Try to find a destination for indirect edge IE that corresponds to a virtual call based on a formal parameter which is described by jump function JFUNC and if it can be determined, make it direct and return the direct edge. @@ -2714,7 +2751,10 @@ try_make_edge_direct_virtual_call (struct cgraph_edge *ie, { tree binfo, target; - if (!flag_devirtualize) + if (!flag_devirtualize + /* FIXME_LIPO -- LIPO is not yet compatible + with ipa devirt. */ + || flag_dyn_ipa) return NULL; /* First try to do lookup via known virtual table pointer value. */ @@ -2735,15 +2775,7 @@ try_make_edge_direct_virtual_call (struct cgraph_edge *ie, && DECL_FUNCTION_CODE (target) == BUILT_IN_UNREACHABLE) || !possible_polymorphic_call_target_p (ie, cgraph_get_node (target))) - { - if (dump_file) - fprintf (dump_file, - "Type inconsident devirtualization: %s/%i->%s\n", - ie->caller->name (), ie->caller->order, - IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (target))); - target = builtin_decl_implicit (BUILT_IN_UNREACHABLE); - cgraph_get_create_node (target); - } + target = ipa_impossible_devirt_target (ie, target); return ipa_make_edge_direct_to_target (ie, target); } } @@ -2773,10 +2805,7 @@ try_make_edge_direct_virtual_call (struct cgraph_edge *ie, if (targets.length () == 1) target = targets[0]->decl; else - { - target = builtin_decl_implicit (BUILT_IN_UNREACHABLE); - cgraph_get_create_node (target); - } + target = ipa_impossible_devirt_target (ie, NULL_TREE); } else { @@ -2791,10 +2820,8 @@ try_make_edge_direct_virtual_call (struct cgraph_edge *ie, if (target) { -#ifdef ENABLE_CHECKING - gcc_assert (possible_polymorphic_call_target_p - (ie, cgraph_get_node (target))); -#endif + if (!possible_polymorphic_call_target_p (ie, cgraph_get_node (target))) + target = ipa_impossible_devirt_target (ie, target); return ipa_make_edge_direct_to_target (ie, target); } else @@ -2877,16 +2904,20 @@ update_indirect_edges_after_inlining (struct cgraph_edge *cs, else if (jfunc->type == IPA_JF_PASS_THROUGH && ipa_get_jf_pass_through_operation (jfunc) == NOP_EXPR) { - if (ici->agg_contents - && !ipa_get_jf_pass_through_agg_preserved (jfunc)) + if ((ici->agg_contents + && !ipa_get_jf_pass_through_agg_preserved (jfunc)) + || (ici->polymorphic + && !ipa_get_jf_pass_through_type_preserved (jfunc))) ici->param_index = -1; else ici->param_index = ipa_get_jf_pass_through_formal_id (jfunc); } else if (jfunc->type == IPA_JF_ANCESTOR) { - if (ici->agg_contents - && !ipa_get_jf_ancestor_agg_preserved (jfunc)) + if ((ici->agg_contents + && !ipa_get_jf_ancestor_agg_preserved (jfunc)) + || (ici->polymorphic + && !ipa_get_jf_ancestor_type_preserved (jfunc))) ici->param_index = -1; else { @@ -3650,6 +3681,7 @@ ipa_modify_formal_parameters (tree fndecl, ipa_parm_adjustment_vec adjustments) TREE_TYPE (fndecl) = new_type; DECL_VIRTUAL_P (fndecl) = 0; + DECL_LANG_SPECIFIC (fndecl) = NULL; otypes.release (); oparms.release (); } |