[pretty-ipa] Enable IPA nothrow discovery

Richard Guenther richard.guenther@gmail.com
Tue Apr 14 08:34:00 GMT 2009


On Mon, Apr 13, 2009 at 7:16 PM, Jan Hubicka <hubicka@ucw.cz> wrote:
> Hi,
> this patch make ipa-pure-const to set NOTHROW flags in the IPA mode I promised
> while merging the ipa-pure-const reqrite.  There was two major problems here; firstly
> the ipa-pure-const propgate properties over all edges, while throwing calls
> make callers throwing only when things are not caught locally.
> So I added hook to ipa_utils_reduced_inorder to compute inorder for cases
> where we ignore some edges, added flag to cgraph edges specifying if they
> can end up throwing externally and made ipa-pure-const to propagate only this way.
>
> This makes pass to find 400 new nothrow flags on tramp3d compared to version
> propagating over all edges that found only 60. Tramp3d is not best testcase
> here; acyclic graphs are well handled by early optimizers.  So in fact I am quite
> surprised there are so many extra nothrow functions found and will look into why.
>
> Second problem was the fact that making function NOTHROW requires fixup_cfg
> to be performed on the callers, otherwise verify_stmt fails.  Passmanager
> calls verify_ssa and verify_stmt on all bodies in between IPA passes, so it
> gets false positives here.  This is fixed by relaxing this check in verify_stmt
> when in IPA mode.
>
> There is still one issue left: when there is local handler that continue
> throwing externally via RESX that is reached only via possibly throwing
> calls, proving the calles non-throwing will not make caller non-throwing
> since we mark it locally throwing when visiting the RESX.  This can be
> fixed: when visiting RESX look for all EH edges that leads to this RESX
> and if they are all calls, mark them all throwing externally.  This
> seems like case that we can be interested to handle well, since local
> cleanups are common, but I will do this incrementally.
>
> I plan to commit the patch today to pretty-ipa for further testing and if there
> are no complains, I will prepare mainline version and merge next week.
>
> Honza
>
>        * cgraph.c (cgraph_make_edge, dump_cgraph_node, cgraph_set_call_stmt):
>        Set nothrow flag.
>        * cgraph.h (struct function): Reduce loop_nest to 30 bits; add
>        can_throw_external flag.
>        * ipa-reference.c (ipa_utils_reduced_inorder): Update call.
>        * ipa-pure-const.c (ignore_edge): New function.
>        (propagate): Compute order for NOTHROW computation; set NOTHROWs
>        only over can_throw_external edges.
>        (local_pure_const): Add nothrow flag.
>        * ipa-utils.c (searchc): Add ignore_edge callback.
>        (ipa_utils_reduced_inorder): Add ignore_edge callback.
>        * ipa-utils.h (ipa_utils_reduced_inorder): Update prototype.
>        (set_nothrow_function_flags): Update cgraph.
>        * tree-cfg.c (verify_stmt): Relax nothrow checking when in IPA mode.
> Index: cgraph.c
> ===================================================================
> --- cgraph.c    (revision 146003)
> +++ cgraph.c    (working copy)
> @@ -639,6 +639,7 @@
>                                 htab_hash_pointer (e->call_stmt));
>     }
>   e->call_stmt = new_stmt;
> +  e->can_throw_external = stmt_can_throw_external (new_stmt);
>   if (e->caller->call_site_hash)
>     {
>       void **slot;
> @@ -667,7 +668,6 @@
>     for (node = orig->clones; node != orig;)
>       {
>        struct cgraph_edge *edge = cgraph_edge (node, old_stmt);
> -
>        if (edge)
>          cgraph_set_call_stmt (edge, new_stmt);
>        if (node->clones)
> @@ -774,6 +774,7 @@
>   edge->caller = caller;
>   edge->callee = callee;
>   edge->call_stmt = call_stmt;
> +  edge->can_throw_external = stmt_can_throw_external (call_stmt);
>   edge->prev_caller = NULL;
>   edge->next_caller = callee->callers;
>   if (callee->callers)
> @@ -1386,6 +1387,8 @@
>        fprintf(f, "(inlined) ");
>       if (edge->indirect_call)
>        fprintf(f, "(indirect) ");
> +      if (edge->can_throw_external)
> +       fprintf(f, "(can throw external) ");
>     }
>
>   fprintf (f, "\n  calls: ");
> Index: cgraph.h
> ===================================================================
> --- cgraph.h    (revision 146003)
> +++ cgraph.h    (working copy)
> @@ -248,9 +248,11 @@
>      per function call.  The range is 0 to CGRAPH_FREQ_MAX.  */
>   int frequency;
>   /* Depth of loop nest, 1 means no loop nest.  */
> -  unsigned int loop_nest : 31;
> +  unsigned int loop_nest : 30;
>   /* Whether this edge describes a call that was originally indirect.  */
>   unsigned int indirect_call : 1;
> +  /* Can this call throw external
>

Patch truncated?

The overall idea looks ok though.

Thanks,
Richard.



More information about the Gcc-patches mailing list