Makefile.in (tree-ssa-phiopt.o): Depends on flags.h.
authorAndrew Pinski <pinskia@physics.uc.edu>
Tue, 18 May 2004 17:32:54 +0000 (17:32 +0000)
committerJeff Law <law@gcc.gnu.org>
Tue, 18 May 2004 17:32:54 +0000 (11:32 -0600)
        * 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 <law@redhat.com>
From-SVN: r81999

gcc/ChangeLog
gcc/Makefile.in
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/tree-ssa/20040518-1.c [new file with mode: 0644]
gcc/tree-ssa-phiopt.c

index a294e940cfe7c8c6e97297dab4b7d30e78ee655e..06df3c2d483260269ac549d3ee0ec6ab908437c4 100644 (file)
@@ -1,3 +1,14 @@
+2004-05-18  Andrew Pinski  <pinskia@physics.uc.edu>
+           Jeff Law <law@redhat.com>
+
+       * 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  <law@redhat.com>
 
        * tree-ssa-phiopt.c (replace_phi_with_stmt): New function extracted
index 39fbe32f85465b3f1e8a9448268bdd84589dd8b6..804aa5ea88a91b7bdb7b9c7961801c678d7c4606 100644 (file)
@@ -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 \
index 911b84092b914daf74759de559f90c7a1751b733..fcf983fbd7dcb6e3a903d5317731e7edabdb93f0 100644 (file)
@@ -1,3 +1,7 @@
+2004-05-18  Andrew Pinski  <pinskia@physics.uc.edu>
+
+       * gcc.dg/tree-ssa/20040518-1.c: New test.
+
 2004-05-18  Zack Weinberg  <zack@codesourcery.com>
 
        * 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 (file)
index 0000000..f80a74a
--- /dev/null
@@ -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"} } */
index a29b8f71a9498bc5832d4a2015669eda72f25b6c..bc339c808bf7e15fe7b2bbd100fd07355bc49ece 100644 (file)
@@ -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.  */