[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