From 3a3f4da9377970c5cfd96dc7f4717427384263c4 Mon Sep 17 00:00:00 2001 From: Andrew Pinski Date: Tue, 18 May 2004 17:32:54 +0000 Subject: [PATCH] Makefile.in (tree-ssa-phiopt.o): Depends on flags.h. * Makefile.in (tree-ssa-phiopt.o): Depends on flags.h. * tree-ssa-phiopt.c: Include flags.h. (conditional_replacement): Remove argument names from prototype. Minor formatting and comment fixes. (tree_ssa_phiopt): If conditional_replacement returns false, then call value_replacement. (value_replacement): New function. * gcc.dg/tree-ssa/20040518-1.c: New test. Co-Authored-By: Jeff Law From-SVN: r81999 --- gcc/ChangeLog | 11 ++ gcc/Makefile.in | 2 +- gcc/testsuite/ChangeLog | 4 + gcc/testsuite/gcc.dg/tree-ssa/20040518-1.c | 12 +++ gcc/tree-ssa-phiopt.c | 115 ++++++++++++++++++--- 5 files changed, 129 insertions(+), 15 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/20040518-1.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a294e940cfe..06df3c2d483 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +2004-05-18 Andrew Pinski + Jeff Law + + * Makefile.in (tree-ssa-phiopt.o): Depends on flags.h. + * tree-ssa-phiopt.c: Include flags.h. + (conditional_replacement): Remove argument names from prototype. + Minor formatting and comment fixes. + (tree_ssa_phiopt): If conditional_replacement returns false, then + call value_replacement. + (value_replacement): New function. + 2004-05-18 Jeff Law * tree-ssa-phiopt.c (replace_phi_with_stmt): New function extracted diff --git a/gcc/Makefile.in b/gcc/Makefile.in index 39fbe32f854..804aa5ea88a 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -1581,7 +1581,7 @@ tree-ssa-forwprop.o : tree-ssa-forwprop.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ $(TREE_FLOW_H) tree-pass.h $(TREE_DUMP_H) tree-ssa-phiopt.o : tree-ssa-phiopt.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ $(TM_H) errors.h $(GGC_H) $(TREE_H) $(RTL_H) $(TM_P_H) $(BASIC_BLOCK_H) \ - $(TREE_FLOW_H) tree-pass.h $(TREE_DUMP_H) langhooks.h + $(TREE_FLOW_H) tree-pass.h $(TREE_DUMP_H) langhooks.h flags.h tree-nrv.o : tree-nrv.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ $(TM_H) $(TREE_H) $(RTL_H) function.h $(BASIC_BLOCK_H) $(EXPR_H) \ diagnostic.h $(TREE_FLOW_H) $(TIMEVAR_H) $(TREE_DUMP_H) tree-pass.h \ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 911b84092b9..fcf983fbd7d 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2004-05-18 Andrew Pinski + + * gcc.dg/tree-ssa/20040518-1.c: New test. + 2004-05-18 Zack Weinberg * gcc.c-torture/execute/991216-3.c: Delete, duplicate of 991216-2.c. diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20040518-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20040518-1.c new file mode 100644 index 00000000000..f80a74a14ea --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/20040518-1.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -fdump-tree-phiopt1-details" } */ +int f(int a, int b) +{ + int c = b; + if (a != b) + c = a; + return c; +} + +/* Should have no ifs left after straightening. */ +/* { dg-final { scan-tree-dump-times "if " 0 "phiopt1"} } */ diff --git a/gcc/tree-ssa-phiopt.c b/gcc/tree-ssa-phiopt.c index a29b8f71a94..bc339c808bf 100644 --- a/gcc/tree-ssa-phiopt.c +++ b/gcc/tree-ssa-phiopt.c @@ -26,6 +26,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include "ggc.h" #include "tree.h" #include "rtl.h" +#include "flags.h" #include "tm_p.h" #include "basic-block.h" #include "timevar.h" @@ -36,15 +37,14 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include "langhooks.h" static void tree_ssa_phiopt (void); -static bool conditional_replacement (basic_block bb, tree phi, tree arg0, - tree arg1); +static bool conditional_replacement (basic_block, tree, tree, tree); +static bool value_replacement (basic_block, tree, tree, tree); static void replace_phi_with_stmt (block_stmt_iterator, basic_block, basic_block, tree, tree); static bool candidate_bb_for_phi_optimization (basic_block, basic_block *, basic_block *); - /* This pass eliminates PHI nodes which can be trivially implemented as an assignment from a conditional expression. ie if we have something like: @@ -64,7 +64,25 @@ static bool candidate_bb_for_phi_optimization (basic_block, bb1 will become unreachable and bb0 and bb2 will almost always be merged into a single block. This occurs often due to gimplification - of conditionals. */ + of conditionals. + + Also done is the following optimization: + + bb0: + if (a != b) goto bb2; else goto bb1; + bb1: + bb2: + x = PHI (a (bb1), b (bb0)) + + We can rewrite that as: + + bb0: + bb1: + bb2: + x = b; + + This can sometimes occur as a result of other optimizations. A + similar transformation is done by the ifcvt RTL optimizer. */ static void tree_ssa_phiopt (void) @@ -77,7 +95,6 @@ tree_ssa_phiopt (void) { tree arg0, arg1, phi; - /* We're searching for blocks with one PHI node which has two arguments. */ phi = phi_nodes (bb); @@ -88,12 +105,13 @@ tree_ssa_phiopt (void) arg1 = PHI_ARG_DEF (phi, 1); /* Do the replacement of conditional if it can be done. */ - if (conditional_replacement (bb, phi, arg0, arg1)) - { - /* We have done the replacement so we need to rebuild the cfg. */ - removed_phis = true; - continue; - } + if (conditional_replacement (bb, phi, arg0, arg1) + || value_replacement (bb, phi, arg0, arg1)) + { + /* We have done the replacement so we need to rebuild the + cfg when this pass is complete. */ + removed_phis = true; + } } } @@ -294,8 +312,7 @@ conditional_replacement (basic_block bb, tree phi, tree arg0, tree arg1) TREE_OPERAND (old_result, 0), TREE_OPERAND (old_result, 1)); - new1 = build (MODIFY_EXPR, TREE_TYPE (result), - new_var, new1); + new1 = build (MODIFY_EXPR, TREE_TYPE (result), new_var, new1); bsi_insert_after (&bsi, new1, BSI_NEW_STMT); } @@ -330,7 +347,7 @@ conditional_replacement (basic_block bb, tree phi, tree arg0, tree arg1) cond = cond1; /* If what we get back is a conditional expression, there is no - way that is can be gimple. */ + way that it can be gimple. */ if (TREE_CODE (cond) == COND_EXPR) return false; @@ -360,6 +377,76 @@ conditional_replacement (basic_block bb, tree phi, tree arg0, tree arg1) return true; } +/* The function value_replacement does the main work of doing the value + replacement. 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 the PHI. Likewise for ARG1. */ + +static bool +value_replacement (basic_block bb, tree phi, tree arg0, tree arg1) +{ + tree result; + basic_block other_block = NULL; + basic_block cond_block = NULL; + tree new, cond; + edge true_edge, false_edge; + + /* If the type says honor signed zeros we cannot do this + optimization. */ + if (HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg1)))) + return false; + + if (!candidate_bb_for_phi_optimization (bb, &cond_block, &other_block)) + return false; + + cond = COND_EXPR_COND (last_stmt (cond_block)); + result = PHI_RESULT (phi); + + /* This transformation is only valid for equality comparisons. */ + if (TREE_CODE (cond) != NE_EXPR && TREE_CODE (cond) != EQ_EXPR) + return false; + + /* We need to know which is the true edge and which is the false + edge so that we know if have abs or negative abs. */ + extract_true_false_edges_from_block (cond_block, &true_edge, &false_edge); + + /* At this point we know we have a COND_EXPR with two successors. + One successor is BB, the other successor is an empty block which + falls through into BB. + + The condition for the COND_EXPR is known to be NE_EXPR or EQ_EXPR. + + There is a single PHI node at the join point (BB) with two arguments. + + We now need to verify that the two arguments in the PHI node match + the two arguments to the equality comparison. */ + + if ((operand_equal_p (arg0, TREE_OPERAND (cond, 0), 0) + && operand_equal_p (arg1, TREE_OPERAND (cond, 1), 0)) + || (operand_equal_p (arg1, TREE_OPERAND (cond, 0), 0) + && operand_equal_p (arg0, TREE_OPERAND (cond, 1), 0))) + { + edge e; + tree arg; + + e = (TREE_CODE (cond) == NE_EXPR ? true_edge : false_edge); + if (PHI_ARG_EDGE (phi, 0) == e) + arg = arg0; + else + arg = arg1; + + /* Build the new assignment. */ + new = build (MODIFY_EXPR, TREE_TYPE (result), result, arg); + + replace_phi_with_stmt (bsi_start (bb), bb, cond_block, phi, new); + + /* Note that we optimized this PHI. */ + return true; + } + return false; +} + /* Always do these optimizations if we have SSA trees to work on. */ -- 2.30.2