On Mon, Nov 25, 2013 at 6:12 PM, Jan Hubicka <hubi...@ucw.cz> wrote:
> Hi,
> I am looking into testcases for individual code paths of ipa-devirt and my 
> life
> would be much easier if gimple-fold did not take some of them by old code.
> This patch also improves code by doing devirtualization earlier in the game
> since get_polymorphic_call_info is now supperset of
> gimple_extract_devirt_binfo_from_cst but with more tricks in it.
>
> I does some SSA graph walking that may break when folding is called with 
> broken
> SSA form, but since other places in gimple-fold does that, too, I hope it is
> OK.

Walking via SSA_NAME_DEF_STMT is ok you just are not allowed to
rely on up-to-date immediate uses (thus, update_stmt may not have
been called).

> Bootstrapped/regtested x86_64-linux, OK?

As you are only interested in cases of zero or exactly one possible
call target is it possible to shortcut the machinery to make it cheaper?

Otherwise ok.  Please work on the bugs all this IPA stuff exposed - there
are failing SPEC cases because of it.  See for example PRs 59208
and 59226.

Thanks,
Richard.

> Honza
>
>         * ipa-utils.h (possible_polymorphic_call_targets): Determine context 
> of
>         the call.
>         (gimple_fold_call): Use ipa-devirt to devirtualize.
>
> Index: ipa-utils.h
> ===================================================================
> *** ipa-utils.h (revision 205108)
> --- ipa-utils.h (working copy)
> *************** possible_polymorphic_call_targets (tree
> *** 121,130 ****
>                                    bool *final = NULL,
>                                    void **cache_token = NULL)
>   {
>     return possible_polymorphic_call_targets (obj_type_ref_class (call),
>                                             tree_to_uhwi
>                                               (OBJ_TYPE_REF_TOKEN (call)),
> !                                           
> ipa_dummy_polymorphic_call_context,
>                                             final, cache_token);
>   }
>
> --- 121,137 ----
>                                    bool *final = NULL,
>                                    void **cache_token = NULL)
>   {
> +   tree otr_type;
> +   HOST_WIDE_INT otr_token;
> +   ipa_polymorphic_call_context context;
> +
> +   get_polymorphic_call_info (current_function_decl,
> +                            call,
> +                            &otr_type, &otr_token, &context);
>     return possible_polymorphic_call_targets (obj_type_ref_class (call),
>                                             tree_to_uhwi
>                                               (OBJ_TYPE_REF_TOKEN (call)),
> !                                           context,
>                                             final, cache_token);
>   }
>
> Index: gimple-fold.c
> ===================================================================
> *** gimple-fold.c       (revision 205108)
> --- gimple-fold.c       (working copy)
> *************** gimple_fold_call (gimple_stmt_iterator *
> *** 1151,1174 ****
>         }
>         else if (virtual_method_call_p (callee))
>         {
> !         tree obj = OBJ_TYPE_REF_OBJECT (callee);
> !         tree binfo = gimple_extract_devirt_binfo_from_cst
> !                (obj, obj_type_ref_class (callee));
> !         if (binfo)
>             {
> !             HOST_WIDE_INT token
> !               = TREE_INT_CST_LOW (OBJ_TYPE_REF_TOKEN (callee));
> !             tree fndecl = gimple_get_virt_method_for_binfo (token, binfo);
> !             if (fndecl)
> !               {
> ! #ifdef ENABLE_CHECKING
> !                 gcc_assert (possible_polymorphic_call_target_p
> !                                (callee, cgraph_get_node (fndecl)));
> !
> ! #endif
> !                 gimple_call_set_fndecl (stmt, fndecl);
> !                 changed = true;
> !               }
>             }
>         }
>       }
> --- 1151,1168 ----
>         }
>         else if (virtual_method_call_p (callee))
>         {
> !         bool final;
> !         vec <cgraph_node *>targets
> !           = possible_polymorphic_call_targets (callee, &final);
> !         if (final && targets.length () <= 1)
>             {
> !             tree fndecl;
> !             if (targets.length () == 1)
> !               fndecl = targets[0]->decl;
> !             else
> !               fndecl = builtin_decl_implicit (BUILT_IN_UNREACHABLE);
> !             gimple_call_set_fndecl (stmt, fndecl);
> !             changed = true;
>             }
>         }
>       }

Reply via email to