[PATCH v5 1/4] Match: Add interface match_cond_with_binary_phi for true/false arg

Richard Biener richard.guenther@gmail.com
Thu Sep 19 06:21:29 GMT 2024


On Thu, Sep 19, 2024 at 6:11 AM <pan2.li@intel.com> wrote:
>
> From: Pan Li <pan2.li@intel.com>
>
> When matching the cond with 2 args phi node, we need to figure out
> which arg of phi node comes from the true edge of cond block, as
> well as the false edge.  This patch would like to add interface
> to perform the action and return the true and false arg in TREE type.
>
> The below test suites are passed for this patch.
> * The rv64gcv fully regression test.
> * The x86 bootstrap test.
> * The x86 fully regression test.

OK.

Thanks,
Richard.

> gcc/ChangeLog:
>
>         * gimple-match-head.cc (match_cond_with_binary_phi): Add new func
>         impl to match binary phi for true and false arg.
>
> Signed-off-by: Pan Li <pan2.li@intel.com>
> ---
>  gcc/gimple-match-head.cc | 120 +++++++++++++++++++++++++++++++++++++++
>  1 file changed, 120 insertions(+)
>
> diff --git a/gcc/gimple-match-head.cc b/gcc/gimple-match-head.cc
> index 924d3f1e710..b63b66e9485 100644
> --- a/gcc/gimple-match-head.cc
> +++ b/gcc/gimple-match-head.cc
> @@ -375,3 +375,123 @@ gimple_bitwise_inverted_equal_p (tree expr1, tree expr2, bool &wascmp, tree (*va
>      return true;
>    return false;
>  }
> +
> +/*
> + * Return the relevant gcond * of the given phi, as well as the true
> + * and false TREE args of the phi.  Or return nullptr.
> + *
> + * If matched the gcond *, the output argument TREE true_arg and false_arg
> + * will be updated to the relevant args of phi.
> + *
> + * If failed to match, nullptr gcond * will be returned, as well as the output
> + * arguments will be set to NULL_TREE.
> + */
> +
> +static inline gcond *
> +match_cond_with_binary_phi (gphi *phi, tree *true_arg, tree *false_arg)
> +{
> +  *true_arg = *false_arg = NULL_TREE;
> +
> +  if (gimple_phi_num_args (phi) != 2)
> +    return nullptr;
> +
> +  basic_block pred_b0 = EDGE_PRED (gimple_bb (phi), 0)->src;
> +  basic_block pred_b1 = EDGE_PRED (gimple_bb (phi), 1)->src;
> +  edge edge_for_pred_0 = nullptr;
> +
> +  if (EDGE_COUNT (pred_b0->succs) == 2
> +      && EDGE_COUNT (pred_b1->succs) == 1
> +      && EDGE_COUNT (pred_b1->preds) == 1
> +      && pred_b0 == EDGE_PRED (gimple_bb (phi), 0)->src)
> +    /*
> +     * +------+
> +     * | b0:  |
> +     * | def  |       +-----+
> +     * | ...  |       | b1: |
> +     * | cond |------>| def |
> +     * +------+       | ... |
> +     *    |           +-----+
> +     *    #              |
> +     *    |              |
> +     *    v              |
> +     * +-----+           |
> +     * | b2: |           |
> +     * | def |<----------+
> +     * +-----+
> +     * #: edge_for_pred_0.
> +     */
> +    edge_for_pred_0 = EDGE_PRED (gimple_bb (phi), 0);
> +  else if (EDGE_COUNT (pred_b1->succs) == 2
> +          && EDGE_COUNT (pred_b0->succs) == 1
> +          && EDGE_COUNT (pred_b0->preds) == 1
> +          && pred_b1 == EDGE_PRED (pred_b0, 0)->src)
> +    /*
> +     *                +------+
> +     *                | b1:  |
> +     * +-----+        | def  |
> +     * | b0: |        | ...  |
> +     * | def |<---#---| cond |
> +     * | ... |        +------+
> +     * +-----+           |
> +     *    |              |
> +     *    |              |
> +     *    |              |
> +     *    v              |
> +     * +-----+           |
> +     * | b2: |           |
> +     * | def |<----------+
> +     * +-----+
> +     * #: edge_for_pred_0.
> +     */
> +    edge_for_pred_0 = EDGE_PRED (pred_b0, 0);
> +  else if (EDGE_COUNT (pred_b0->succs) == 1
> +          && EDGE_COUNT (pred_b1->succs) == 1
> +          && EDGE_COUNT (pred_b0->preds) == 1
> +          && EDGE_COUNT (pred_b1->preds) == 1
> +          && EDGE_COUNT (EDGE_PRED (pred_b0, 0)->src->succs) == 2
> +          && EDGE_PRED (pred_b0, 0)->src == EDGE_PRED (pred_b1, 0)->src)
> +    /* +------+
> +     * | b0:  |
> +     * | ...  |       +-----+
> +     * | cond |------>| b2: |
> +     * +------+       | ... |
> +     *    |           +-----+
> +     *    #              |
> +     *    |              |
> +     *    v              |
> +     * +-----+           |
> +     * | b1: |           |
> +     * | ... |           |
> +     * +-----+           |
> +     *    |              |
> +     *    |              |
> +     *    v              |
> +     * +-----+           |
> +     * | b3: |<----------+
> +     * | ... |
> +     * +-----+
> +     * #: edge_for_pred_0.
> +     */
> +    edge_for_pred_0 = EDGE_PRED (pred_b0, 0);
> +
> +  if (!edge_for_pred_0)
> +    return nullptr;
> +
> +  gcond *cond = safe_dyn_cast <gcond *> (*gsi_last_bb (edge_for_pred_0->src));
> +
> +  if (!cond)
> +    return nullptr;
> +
> +  if (edge_for_pred_0->flags & EDGE_TRUE_VALUE)
> +    {
> +      *true_arg = gimple_phi_arg_def (phi, 0);
> +      *false_arg = gimple_phi_arg_def (phi, 1);
> +    }
> +  else /* Aka edge_for_pred_0->flags & EDGE_FALSE_VALUE  */
> +    {
> +      *false_arg = gimple_phi_arg_def (phi, 0);
> +      *true_arg = gimple_phi_arg_def (phi, 1);
> +    }
> +
> +  return cond;
> +}
> --
> 2.43.0
>


More information about the Gcc-patches mailing list