summaryrefslogtreecommitdiff
path: root/0061-Backport-Replace-conditional_replacement-with-match-.patch
diff options
context:
space:
mode:
authorCoprDistGit <infra@openeuler.org>2023-10-17 02:15:03 +0000
committerCoprDistGit <infra@openeuler.org>2023-10-17 02:15:03 +0000
commitd82826d1a1c7ea45a761dfbf76b879712c7332ec (patch)
tree973a28470803b27c914f813f43d43f8932763ea3 /0061-Backport-Replace-conditional_replacement-with-match-.patch
parentb868000cf68cec0c9cd45fbf89a83173dea7c5eb (diff)
automatic import of gccopeneuler22.03_LTS
Diffstat (limited to '0061-Backport-Replace-conditional_replacement-with-match-.patch')
-rw-r--r--0061-Backport-Replace-conditional_replacement-with-match-.patch249
1 files changed, 249 insertions, 0 deletions
diff --git a/0061-Backport-Replace-conditional_replacement-with-match-.patch b/0061-Backport-Replace-conditional_replacement-with-match-.patch
new file mode 100644
index 0000000..12808be
--- /dev/null
+++ b/0061-Backport-Replace-conditional_replacement-with-match-.patch
@@ -0,0 +1,249 @@
+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
+