re PR tree-optimization/14466 (missed PHI optimization (different types))
authorAndrew Pinski <pinskia@physics.uc.edu>
Fri, 14 May 2004 15:27:37 +0000 (15:27 +0000)
committerAndrew Pinski <pinskia@gcc.gnu.org>
Fri, 14 May 2004 15:27:37 +0000 (08:27 -0700)
2004-05-14  Andrew Pinski  <pinskia@physics.uc.edu>

          PR optimization/14466
        * tree-complex.c (make_temp): Remove.
        (gimplify_val): Replace make_temp with make_rename_temp
        and add NULL as the second argument.
        (expand_complex_div_wide): Likewise.
        * tree-dfa.c (make_rename_temp): New function.
        * tree-flow.h (make_rename_temp): Declare.
        * tree-sra.c (make_temp): Remove.
        (lookup_scalar): Replace make_temp with make_rename_temp.
        (create_scalar_copies): Likewise.
        * tree-ssa-phiopt.c (conditional_replacement): When we
        get non gimple create a temporary variable to hold the
        casted expression.

2004-05-14  Andrew Pinski  <pinskia@physics.uc.edu>

        PR optimization/14466
        * gcc.dg/tree-ssa/20040514-1.c: New test.

From-SVN: r81847

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/tree-ssa/20040514-1.c [new file with mode: 0644]
gcc/tree-complex.c
gcc/tree-dfa.c
gcc/tree-flow.h
gcc/tree-sra.c
gcc/tree-ssa-live.h
gcc/tree-ssa-phiopt.c

index 968a23f9336b021a5efd6a56f4d8236324744d5d..97cb0440a855eaf3261318dcbc46c4a450d3cb68 100644 (file)
@@ -1,3 +1,19 @@
+2004-05-14  Andrew Pinski  <pinskia@physics.uc.edu>
+
+       PR optimization/14466
+       * tree-complex.c (make_temp): Remove.
+       (gimplify_val): Replace make_temp with make_rename_temp
+       and add NULL as the second argument.
+       (expand_complex_div_wide): Likewise.
+       * tree-dfa.c (make_rename_temp): New function.
+       * tree-flow.h (make_rename_temp): Declare.
+       * tree-sra.c (make_temp): Remove.
+       (lookup_scalar): Replace make_temp with make_rename_temp.
+       (create_scalar_copies): Likewise.
+       * tree-ssa-phiopt.c (conditional_replacement): When we
+       get non gimple create a temporary variable to hold the
+       casted expression.
+
 2004-05-14  Paul Brook  <paul@codesourcery.com>
 
        * stor-layout.c (update_alignment_for_field): Use
index eb609b052209bc743cc27175f3feb24c40437993..37ea91eb1bf5199f23193975ede9945d589001bb 100644 (file)
@@ -1,3 +1,7 @@
+2004-05-14  Andrew Pinski  <pinskia@physics.uc.edu>
+
+       * gcc.dg/tree-ssa/20040514-1.c: New test.
+
 2004-05-14  Tobias Schlueter  <tobias.schlueter@physik.uni-muenchen.de>
 
        * gfortran.fortran-torture/compile/noncontinuation_1.f90: New 
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20040514-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20040514-1.c
new file mode 100644 (file)
index 0000000..51f4b0f
--- /dev/null
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-phiopt1-details" } */
+
+int t( int i)
+{
+  int j;
+  if(i ==0)
+  {
+   j = 1;
+   goto end;
+  }
+  j = 0;
+end:
+  return j;
+
+/* Should have no ifs left after straightening.  */
+/* { dg-final { scan-tree-dump-times "if " 0 "phiopt1"} } */
index 8094d950da3b60632b8f18d3e892c5d2771b8185..66fa6129c6da5fbb4c10a72e82546b6748371d54 100644 (file)
@@ -30,17 +30,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include "flags.h"
 
 
-/* Build a temporary.  Make sure and register it to be renamed.  */
-
-static tree
-make_temp (tree type)
-{
-  tree t = create_tmp_var (type, NULL);
-  add_referenced_tmp_var (t);
-  bitmap_set_bit (vars_to_rename, var_ann (t)->uid);
-  return t;
-}
-
 /* Force EXP to be a gimple_val.  */
 
 static tree
@@ -51,7 +40,7 @@ gimplify_val (block_stmt_iterator *bsi, tree type, tree exp)
   if (is_gimple_val (exp))
     return exp;
 
-  t = make_temp (type);
+  t = make_rename_temp (type, NULL);
   new_stmt = build (MODIFY_EXPR, type, t, exp);
 
   orig_stmt = bsi_stmt (*bsi);
@@ -251,8 +240,8 @@ expand_complex_div_wide (block_stmt_iterator *bsi, tree inner_type,
       cond = build (COND_EXPR, void_type_node, cond, t1, t2);
       bsi_insert_before (bsi, cond, BSI_SAME_STMT);
 
-      min = make_temp (inner_type);
-      max = make_temp (inner_type);
+      min = make_rename_temp (inner_type, NULL);
+      max = make_rename_temp (inner_type, NULL);
       l3 = create_artificial_label ();
 
       /* Split the original block, and create the TRUE and FALSE blocks.  */
index 2a71ef20fe681d6f2596c1090481b99c705e6b95..e94640eee00c7dc95e53a71338fa237f396c06a4 100644 (file)
@@ -486,6 +486,18 @@ create_ssa_name_ann (tree t)
 }
 
 
+/* Build a temporary.  Make sure and register it to be renamed.  */
+
+tree
+make_rename_temp (tree type, const char *prefix)
+{
+  tree t = create_tmp_var (type, prefix);
+  add_referenced_tmp_var (t);
+  bitmap_set_bit (vars_to_rename, var_ann (t)->uid);
+  return t;
+}
+
+
 
 /*---------------------------------------------------------------------------
                              Debugging functions
index 76f97a4ebf59227fc77dd567fb881613bc3d1d01..66995338a40d15b4b3b45c8cc144798a546ccbae 100644 (file)
@@ -510,6 +510,7 @@ extern tree get_virtual_var (tree);
 extern void add_referenced_tmp_var (tree var);
 extern void mark_new_vars_to_rename (tree, bitmap);
 extern void redirect_immediate_uses (tree, tree);
+extern tree make_rename_temp (tree, const char *);
 
 /* Flags used when computing reaching definitions and reached uses.  */
 #define TDFA_USE_OPS           1 << 0
index d447b82d7682588c6a9c7e442c108d17263f1f41..46a3c59e117c188b657a0d5bcc66288361e4a89a 100644 (file)
@@ -112,17 +112,6 @@ sra_elt_eq (const void *x, const void *y)
   return true;
 }
 
-/* Build a temporary.  Make sure and register it to be renamed.  */
-
-static tree
-make_temp (tree type, const char *prefix)
-{
-  tree t = create_tmp_var (type, prefix);
-  add_referenced_tmp_var (t);
-  bitmap_set_bit (vars_to_rename, var_ann (t)->uid);
-  return t;
-}
-
 /* Mark all the variables in VDEF operands for STMT for renaming.
    This becomes necessary when we modify all of a non-scalar.  */
 
@@ -194,7 +183,7 @@ lookup_scalar (struct sra_elt *key, tree type)
       res = xmalloc (sizeof (*res));
       *slot = res;
       *res = *key;
-      res->replace = make_temp (type, "SR");
+      res->replace = make_rename_temp (type, "SR");
 
       if (DECL_NAME (key->base) && !DECL_IGNORED_P (key->base))
        {
@@ -691,7 +680,7 @@ create_scalar_copies (tree lhs, tree rhs, enum sra_copy_mode mode)
       tree stmt, tmp;
 
       /* Add TMP = VA_ARG_EXPR <>  */
-      tmp = make_temp (TREE_TYPE (rhs), NULL);
+      tmp = make_rename_temp (TREE_TYPE (rhs), NULL);
       stmt = csc_assign (&tsi, tmp, rhs);
 
       /* Mark all the variables in VDEF operands for renaming, because
index 2d97a93cfe882e4a5346e47809c6f713d00c34b2..30c33cfb84ba21768237800a68af32d96e5c6e5d 100644 (file)
@@ -72,6 +72,7 @@ extern void change_partition_var (var_map, tree, int);
 extern void compact_var_map (var_map, int);
 extern void remove_ssa_form (FILE *, var_map, int);
 extern void register_ssa_partitions_for_vars (bitmap vars, var_map map);
+extern tree make_ssa_temp (tree);
 
 static inline int num_var_partitions (var_map);
 static inline tree var_to_partition_to_var (var_map, tree);
index ea7a94642def62bfa0532acf72326de82ca0d3f8..c302145393eb8fb160626cd031e866cbf5d981f0 100644 (file)
@@ -37,9 +37,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 
 static void tree_ssa_phiopt (void);
 static bool conditional_replacement (basic_block bb, tree phi, tree arg0,
-                                     tree arg1);
-
-
+                                     tree arg1);                            
+                                  
 /* This pass eliminates PHI nodes which can be trivially implemented as
    an assignment from a conditional expression.  ie if we have something
    like:
@@ -108,11 +107,13 @@ static bool
 conditional_replacement (basic_block bb, tree phi, tree arg0, tree arg1)
 {
   tree result;
+  tree old_result = NULL;
   basic_block other_block = NULL;
   basic_block cond_block = NULL;
   tree last0, last1, new, cond;
   block_stmt_iterator bsi;
   edge true_edge, false_edge;
+  tree new_var = NULL;
 
   /* The PHI arguments have the constants 0 and 1, then convert
     it to the conditional.  */
@@ -172,14 +173,20 @@ conditional_replacement (basic_block bb, tree phi, tree arg0, tree arg1)
     return false;
   
   /* If the condition is not a naked SSA_NAME and its type does not
-      match the type of the result, then we can not optimize this case
-      as it would likely create non-gimple code when the condition
-      was converted to the result's type.  */
+      match the type of the result, then we have to create a new
+      variable to optimize this case as it would likely create
+      non-gimple code when the condition was converted to the
+      result's type.  */
+
   cond = COND_EXPR_COND (last_stmt (cond_block));
   result = PHI_RESULT (phi);
   if (TREE_CODE (cond) != SSA_NAME
       && !lang_hooks.types_compatible_p (TREE_TYPE (cond), TREE_TYPE (result)))
-    return false;
+    {
+      new_var = make_rename_temp (TREE_TYPE (cond), NULL);
+      old_result = cond;
+      cond = new_var;
+    }
   
   /* If the condition was a naked SSA_NAME and the type is not the
       same as the type of the result, then convert the type of the
@@ -190,6 +197,25 @@ conditional_replacement (basic_block bb, tree phi, tree arg0, tree arg1)
   /* 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_block, &true_edge, &false_edge);
+      
+  /* Insert our new statement at the head of our block.  */
+  bsi = bsi_start (bb);
+  
+  if (old_result)
+    {
+      tree new1;
+      if (TREE_CODE_CLASS (TREE_CODE (old_result)) != '<')
+        return false;
+      
+      new1 = build (TREE_CODE (old_result), TREE_TYPE (result),
+                    TREE_OPERAND (old_result, 0),
+                    TREE_OPERAND (old_result, 1));
+      
+      new1 = build (MODIFY_EXPR, TREE_TYPE (result),
+                    new_var, new1);
+      bsi_insert_after (&bsi, new1, BSI_NEW_STMT);
+    }
+  
   
   /* 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
@@ -208,6 +234,7 @@ conditional_replacement (basic_block bb, tree phi, tree arg0, tree arg1)
       false edge as the value zero.  Note that those conditions are not
       the same since only one of the outgoing edges from the COND_EXPR
       will directly reach BB and thus be associated with an argument.  */
+  
   if ((PHI_ARG_EDGE (phi, 0) == true_edge && integer_onep (arg0))
       || (PHI_ARG_EDGE (phi, 0) == false_edge && integer_zerop (arg0))
       || (PHI_ARG_EDGE (phi, 1) == true_edge && integer_onep (arg1))
@@ -218,11 +245,25 @@ conditional_replacement (basic_block bb, tree phi, tree arg0, tree arg1)
     }
   else
     {
-      cond = invert_truthvalue (cond);
-  
+      tree cond1 = invert_truthvalue (cond);
+      
+      cond = cond1;
+      /* If what we get back is a conditional expression, there is no
+        way that is can be gimple.   */
+      if (TREE_CODE (cond) == COND_EXPR)
+       return false; 
+
+      /* If what we get back is not gimple try to create it as gimple by
+         using a temporary variable.   */
       if (is_gimple_cast (cond)
          && !is_gimple_val (TREE_OPERAND (cond, 0)))
-       return false;
+        {
+          tree temp = TREE_OPERAND (cond, 0);
+          tree new_var_1 = make_rename_temp (TREE_TYPE (temp), NULL);
+          new = build (MODIFY_EXPR, TREE_TYPE (new_var_1), new_var_1, temp);
+          bsi_insert_after (&bsi, new, BSI_NEW_STMT);
+          cond = fold_convert (TREE_TYPE (result), new_var_1);
+        }
       
       if (TREE_CODE (cond) == TRUTH_NOT_EXPR
           &&  !is_gimple_val (TREE_OPERAND (cond, 0)))
@@ -232,9 +273,7 @@ conditional_replacement (basic_block bb, tree phi, tree arg0, tree arg1)
                     PHI_RESULT (phi), cond);
     }
   
-  /* Insert our new statement at the head of our block.  */
-  bsi = bsi_start (bb);
-  bsi_insert_after (&bsi, new, BSI_SAME_STMT);
+  bsi_insert_after (&bsi, new, BSI_NEW_STMT);
   
   /* Register our new statement as the defining statement for
       the result.  */
@@ -300,7 +339,8 @@ struct tree_opt_pass pass_phiopt =
   0,                                   /* properties_destroyed */
   0,                                   /* todo_flags_start */
   TODO_dump_func | TODO_ggc_collect    /* todo_flags_finish */
-    | TODO_verify_ssa
+    | TODO_verify_ssa | TODO_rename_vars
+    | TODO_verify_flow
 };