[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