This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [pretty-ipa] Enable IPA nothrow discovery


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.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]