On Fri, Oct 30, 2015 at 12:18 PM, Richard Sandiford
<richard.sandif...@arm.com> wrote:
> It's fairly easy to update the virtual ops when the call has no EH edges,
> which should be cheaper than mark_virtual_operands_for_renaming.
>
> Tested on x86_64-linux-gnu, arm-linux-gnueabi and aarch64-linux-gnu.
> OK to install?

Well.  I think this can be easily improved to handle the EH edge case
by not replacing the virtual uses in the EH region.

Btw, did you verify the pass does things correctly when facing an EH
throwing situation?  It seems all math builtins are marked as NOTHROW
regardless of -fnon-call-exceptions ...

Richard.

> Thanks,
> Richard
>
>
> gcc/
>         * tree-call-cdce.c (join_vdefs): New function.
>         (shrink_wrap_one_built_in_call): Use it when the call does not
>         need to end a block.  Call mark_virtual_operands_for_renaming
>         otherwise.
>         (pass_call_cdce::execute): Don't call
>         mark_virtual_operands_for_renaming here.
>
> diff --git a/gcc/tree-call-cdce.c b/gcc/tree-call-cdce.c
> index 72828dd..dcaa974 100644
> --- a/gcc/tree-call-cdce.c
> +++ b/gcc/tree-call-cdce.c
> @@ -708,6 +708,23 @@ gen_shrink_wrap_conditions (gcall *bi_call, vec<gimple 
> *> conds,
>  /* Probability of the branch (to the call) is taken.  */
>  #define ERR_PROB 0.01
>
> +/* Replace BI_CALL's vdef with a phi that uses BI_CALL's definition
> +   when WITH_CALL is taken and the previous definition when WITHOUT_CALL
> +   is taken.  JOIN_BB is the target of both edges.  */
> +
> +static void
> +join_vdefs (gcall *bi_call, edge with_call, edge without_call,
> +           basic_block join_bb)
> +{
> +  tree old_vuse = gimple_vuse (bi_call);
> +  tree old_vdef = gimple_vdef (bi_call);
> +  tree new_vdef = copy_ssa_name (old_vuse);
> +  gphi *phi = create_phi_node (new_vdef, join_bb);
> +  replace_uses_by (old_vdef, new_vdef);
> +  add_phi_arg (phi, old_vuse, without_call, UNKNOWN_LOCATION);
> +  add_phi_arg (phi, old_vdef, with_call, UNKNOWN_LOCATION);
> +}
> +
>  /* The function to shrink wrap a partially dead builtin call
>     whose return value is not used anywhere, but has to be kept
>     live due to potential error condition.  Returns true if the
> @@ -764,7 +781,8 @@ shrink_wrap_one_built_in_call (gcall *bi_call)
>    bi_call_bb = gimple_bb (bi_call);
>
>    /* Now find the join target bb -- split bi_call_bb if needed.  */
> -  if (stmt_ends_bb_p (bi_call))
> +  bool call_must_end_bb_p = stmt_ends_bb_p (bi_call);
> +  if (call_must_end_bb_p)
>      {
>        /* If the call must be the last in the bb, don't split the block,
>          it could e.g. have EH edges.  */
> @@ -822,6 +840,12 @@ shrink_wrap_one_built_in_call (gcall *bi_call)
>    join_tgt_in_edge_fall_thru->count =
>        guard_bb->count - bi_call_in_edge0->count;
>
> +  if (call_must_end_bb_p)
> +    mark_virtual_operands_for_renaming (cfun);
> +  else
> +    join_vdefs (bi_call, join_tgt_in_edge_from_call,
> +               join_tgt_in_edge_fall_thru, join_tgt_bb);
> +
>    /* Code generation for the rest of the conditions  */
>    basic_block prev_guard_bb = NULL;
>    while (nconds > 0)
> @@ -978,9 +1002,6 @@ pass_call_cdce::execute (function *fun)
>    if (something_changed)
>      {
>        free_dominance_info (CDI_POST_DOMINATORS);
> -      /* As we introduced new control-flow we need to insert PHI-nodes
> -         for the call-clobbers of the remaining call.  */
> -      mark_virtual_operands_for_renaming (fun);
>        return TODO_update_ssa;
>      }
>
>

Reply via email to