代码拉取完成,页面将自动刷新
同步操作将从 src-openEuler/gcc 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
From 406071e8c1838c824f06c35ef3cf9419aa543e6e Mon Sep 17 00:00:00 2001
From: Andrew Pinski <apinski@marvell.com>
Date: Tue, 1 Jun 2021 01:05:09 +0000
Subject: [PATCH 13/35] [Backport] Replace conditional_replacement with match
and simplify
Reference: https://gcc.gnu.org/git/gitweb.cgi?p=gcc.git;h=9f55df63154a39d67ef5b24def7044bf87300831
This is the first of series of patches to simplify phi-opt
to use match and simplify in many cases. This simplification
will more things to optimize.
This is what Richard requested in
https://gcc.gnu.org/pipermail/gcc-patches/2021-May/571197.html
and I think it is the right thing to do too.
OK? Bootstrapped and tested on x86_64-linux-gnu with no regressions.
gcc/ChangeLog:
PR tree-optimization/25290
* tree-ssa-phiopt.c (match_simplify_replacement):
New function.
(tree_ssa_phiopt_worker): Use match_simplify_replacement.
(two_value_replacement): Change the comment about
conditional_replacement.
(conditional_replacement): Delete.
---
gcc/tree-ssa-phiopt.c | 144 ++++++++++++------------------------------
1 file changed, 39 insertions(+), 105 deletions(-)
diff --git a/gcc/tree-ssa-phiopt.c b/gcc/tree-ssa-phiopt.c
index 269eda21c..9fa6363b6 100644
--- a/gcc/tree-ssa-phiopt.c
+++ b/gcc/tree-ssa-phiopt.c
@@ -52,8 +52,8 @@ along with GCC; see the file COPYING3. If not see
static unsigned int tree_ssa_phiopt_worker (bool, bool, bool);
static bool two_value_replacement (basic_block, basic_block, edge, gphi *,
tree, tree);
-static bool conditional_replacement (basic_block, basic_block,
- edge, edge, gphi *, tree, tree);
+static bool match_simplify_replacement (basic_block, basic_block,
+ edge, edge, gphi *, tree, tree);
static gphi *factor_out_conditional_conversion (edge, edge, gphi *, tree, tree,
gimple *);
static int value_replacement (basic_block, basic_block,
@@ -349,8 +349,8 @@ tree_ssa_phiopt_worker (bool do_store_elim, bool do_hoist_loads, bool early_p)
if (!early_p && two_value_replacement (bb, bb1, e2, phi, arg0, arg1))
cfgchanged = true;
else if (!early_p
- && conditional_replacement (bb, bb1, e1, e2, phi,
- arg0, arg1))
+ && match_simplify_replacement (bb, bb1, e1, e2, phi,
+ arg0, arg1))
cfgchanged = true;
else if (abs_replacement (bb, bb1, e1, e2, phi, arg0, arg1))
cfgchanged = true;
@@ -662,7 +662,7 @@ two_value_replacement (basic_block cond_bb, basic_block middle_bb,
}
/* Defer boolean x ? 0 : {1,-1} or x ? {1,-1} : 0 to
- conditional_replacement. */
+ match_simplify_replacement. */
if (TREE_CODE (TREE_TYPE (lhs)) == BOOLEAN_TYPE
&& (integer_zerop (arg0)
|| integer_zerop (arg1)
@@ -763,137 +763,71 @@ two_value_replacement (basic_block cond_bb, basic_block middle_bb,
return true;
}
-/* The function conditional_replacement does the main work of doing the
- conditional replacement. Return true if the replacement is done.
+/* The function match_simplify_replacement does the main work of doing the
+ replacement using match and simplify. Return true if the replacement is done.
Otherwise return false.
BB is the basic block where the replacement is going to be done on. ARG0
is argument 0 from PHI. Likewise for ARG1. */
static bool
-conditional_replacement (basic_block cond_bb, basic_block middle_bb,
- edge e0, edge e1, gphi *phi,
- tree arg0, tree arg1)
+match_simplify_replacement (basic_block cond_bb, basic_block middle_bb,
+ edge e0, edge e1, gphi *phi,
+ tree arg0, tree arg1)
{
- tree result;
gimple *stmt;
- gassign *new_stmt;
tree cond;
gimple_stmt_iterator gsi;
edge true_edge, false_edge;
- tree new_var, new_var2;
- bool neg = false;
- int shift = 0;
- tree nonzero_arg;
-
- /* FIXME: Gimplification of complex type is too hard for now. */
- /* We aren't prepared to handle vectors either (and it is a question
- if it would be worthwhile anyway). */
- if (!(INTEGRAL_TYPE_P (TREE_TYPE (arg0))
- || POINTER_TYPE_P (TREE_TYPE (arg0)))
- || !(INTEGRAL_TYPE_P (TREE_TYPE (arg1))
- || POINTER_TYPE_P (TREE_TYPE (arg1))))
- return false;
+ gimple_seq seq = NULL;
+ tree result;
- /* The PHI arguments have the constants 0 and 1, or 0 and -1 or
- 0 and (1 << cst), then convert it to the conditional. */
- if (integer_zerop (arg0))
- nonzero_arg = arg1;
- else if (integer_zerop (arg1))
- nonzero_arg = arg0;
- else
- return false;
- if (integer_pow2p (nonzero_arg))
- {
- shift = tree_log2 (nonzero_arg);
- if (shift && POINTER_TYPE_P (TREE_TYPE (nonzero_arg)))
- return false;
- }
- else if (integer_all_onesp (nonzero_arg))
- neg = true;
- else
+ if (!empty_block_p (middle_bb))
return false;
- if (!empty_block_p (middle_bb))
+ /* Special case A ? B : B as this will always simplify to B. */
+ if (operand_equal_for_phi_arg_p (arg0, arg1))
return false;
- /* At this point we know we have a GIMPLE_COND with two successors.
+ /* At this point we know we have a GIMPLE_COND with two successors.
One successor is BB, the other successor is an empty block which
falls through into BB.
- There is a single PHI node at the join point (BB) and its arguments
- are constants (0, 1) or (0, -1) or (0, (1 << shift)).
-
- So, given the condition COND, and the two PHI arguments, we can
- rewrite this PHI into non-branching code:
+ There is a single PHI node at the join point (BB).
- dest = (COND) or dest = COND' or dest = (COND) << shift
-
- We use the condition as-is if the argument associated with the
- true edge has the value one or the argument associated with the
- false edge as the value zero. Note that those conditions are not
- the same since only one of the outgoing edges from the GIMPLE_COND
- will directly reach BB and thus be associated with an argument. */
+ So, given the condition COND, and the two PHI arguments, match and simplify
+ can happen on (COND) ? arg0 : arg1. */
stmt = last_stmt (cond_bb);
- result = PHI_RESULT (phi);
/* To handle special cases like floating point comparison, it is easier and
less error-prone to build a tree and gimplify it on the fly though it is
- less efficient. */
- cond = fold_build2_loc (gimple_location (stmt),
- gimple_cond_code (stmt), boolean_type_node,
- gimple_cond_lhs (stmt), gimple_cond_rhs (stmt));
+ less efficient.
+ Don't use fold_build2 here as that might create (bool)a instead of just
+ "a != 0". */
+ cond = build2_loc (gimple_location (stmt),
+ gimple_cond_code (stmt), boolean_type_node,
+ gimple_cond_lhs (stmt), gimple_cond_rhs (stmt));
/* We need to know which is the true edge and which is the false
edge so that we know when to invert the condition below. */
extract_true_false_edges_from_block (cond_bb, &true_edge, &false_edge);
- if ((e0 == true_edge && integer_zerop (arg0))
- || (e0 == false_edge && !integer_zerop (arg0))
- || (e1 == true_edge && integer_zerop (arg1))
- || (e1 == false_edge && !integer_zerop (arg1)))
- cond = fold_build1_loc (gimple_location (stmt),
- TRUTH_NOT_EXPR, TREE_TYPE (cond), cond);
-
- if (neg)
- {
- cond = fold_convert_loc (gimple_location (stmt),
- TREE_TYPE (result), cond);
- cond = fold_build1_loc (gimple_location (stmt),
- NEGATE_EXPR, TREE_TYPE (cond), cond);
- }
- else if (shift)
- {
- cond = fold_convert_loc (gimple_location (stmt),
- TREE_TYPE (result), cond);
- cond = fold_build2_loc (gimple_location (stmt),
- LSHIFT_EXPR, TREE_TYPE (cond), cond,
- build_int_cst (integer_type_node, shift));
- }
+ if (e1 == true_edge || e0 == false_edge)
+ std::swap (arg0, arg1);
- /* Insert our new statements at the end of conditional block before the
- COND_STMT. */
- gsi = gsi_for_stmt (stmt);
- new_var = force_gimple_operand_gsi (&gsi, cond, true, NULL, true,
- GSI_SAME_STMT);
+ tree type = TREE_TYPE (gimple_phi_result (phi));
+ result = gimple_simplify (COND_EXPR, type,
+ cond,
+ arg0, arg1,
+ &seq, NULL);
+ if (!result)
+ return false;
- if (!useless_type_conversion_p (TREE_TYPE (result), TREE_TYPE (new_var)))
- {
- location_t locus_0, locus_1;
+ gsi = gsi_last_bb (cond_bb);
- new_var2 = make_ssa_name (TREE_TYPE (result));
- new_stmt = gimple_build_assign (new_var2, CONVERT_EXPR, new_var);
- gsi_insert_before (&gsi, new_stmt, GSI_SAME_STMT);
- new_var = new_var2;
-
- /* Set the locus to the first argument, unless is doesn't have one. */
- locus_0 = gimple_phi_arg_location (phi, 0);
- locus_1 = gimple_phi_arg_location (phi, 1);
- if (locus_0 == UNKNOWN_LOCATION)
- locus_0 = locus_1;
- gimple_set_location (new_stmt, locus_0);
- }
+ if (seq)
+ gsi_insert_seq_before (&gsi, seq, GSI_SAME_STMT);
- replace_phi_edge_with_variable (cond_bb, e1, phi, new_var);
+ replace_phi_edge_with_variable (cond_bb, e1, phi, result);
/* Note that we optimized this PHI. */
return true;
@@ -3905,7 +3839,7 @@ gate_hoist_loads (void)
Conditional Replacement
-----------------------
- This transformation, implemented in conditional_replacement,
+ This transformation, implemented in match_simplify_replacement,
replaces
bb0:
--
2.27.0.windows.1
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。