On Thu, 16 Oct 2014, Jeff Law wrote:

BTW, I dislike having multiple DCE implementations...
Similarly. The proposal above was just to determine if we should schedule DCE or not.

Thinking about it some more, I don't think we should need any kind of DCE here. The rewriting in update_ssa already does a form of forward propagation that avoids generating dead assignments, the problem only occurs if we explicitly introduce this new assignment. So I believe we should go back to an earlier version, like the attached, which is less work for the compiler.

And now I can go re-read the old discussion (apparently I should avoid gsi_replace, and there may be other ways to handle the coalescing).

--
Marc Glisse
Index: testsuite/gcc.dg/tree-ssa/pr60770-1.c
===================================================================
--- testsuite/gcc.dg/tree-ssa/pr60770-1.c       (revision 0)
+++ testsuite/gcc.dg/tree-ssa/pr60770-1.c       (working copy)
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-O -Wall" } */
+
+int f(int n){
+  int*p;
+  {
+    int yyy=n;
+    p=&yyy;
+  }
+  return *p; /* { dg-warning "yyy" } */
+}
Index: tree-into-ssa.c
===================================================================
--- tree-into-ssa.c     (revision 216384)
+++ tree-into-ssa.c     (working copy)
@@ -1837,26 +1837,35 @@ maybe_register_def (def_operand_p def_p,
 {
   tree def = DEF_FROM_PTR (def_p);
   tree sym = DECL_P (def) ? def : SSA_NAME_VAR (def);
 
   /* If DEF is a naked symbol that needs renaming, create a new
      name for it.  */
   if (marked_for_renaming (sym))
     {
       if (DECL_P (def))
        {
-         tree tracked_var;
-
-         def = make_ssa_name (def, stmt);
+         if (gimple_clobber_p (stmt) && is_gimple_reg (sym))
+           {
+             /* Replace clobber stmts with a default def. This new use of a
+                default definition may make it look like SSA_NAMEs have
+                conflicting lifetimes, so we need special code to let them
+                coalesce properly.  */
+             unlink_stmt_vdef (stmt);
+             gsi_replace (&gsi, gimple_build_nop (), true);
+             def = get_or_create_ssa_default_def (cfun, sym);
+           }
+         else
+           def = make_ssa_name (def, stmt);
          SET_DEF (def_p, def);
 
-         tracked_var = target_for_debug_bind (sym);
+         tree tracked_var = target_for_debug_bind (sym);
          if (tracked_var)
            {
              gimple note = gimple_build_debug_bind (tracked_var, def, stmt);
              /* If stmt ends the bb, insert the debug stmt on the single
                 non-EH edge from the stmt.  */
              if (gsi_one_before_end_p (gsi) && stmt_ends_bb_p (stmt))
                {
                  basic_block bb = gsi_bb (gsi);
                  edge_iterator ei;
                  edge e, ef = NULL;
Index: tree-ssa-live.c
===================================================================
--- tree-ssa-live.c     (revision 216384)
+++ tree-ssa-live.c     (working copy)
@@ -40,20 +40,21 @@ along with GCC; see the file COPYING3.
 #include "stringpool.h"
 #include "tree-ssanames.h"
 #include "expr.h"
 #include "tree-dfa.h"
 #include "timevar.h"
 #include "dumpfile.h"
 #include "tree-ssa-live.h"
 #include "diagnostic-core.h"
 #include "debug.h"
 #include "flags.h"
+#include "tree-ssa.h"
 
 #ifdef ENABLE_CHECKING
 static void  verify_live_on_entry (tree_live_info_p);
 #endif
 
 
 /* VARMAP maintains a mapping from SSA version number to real variables.
 
    All SSA_NAMES are divided into partitions.  Initially each ssa_name is the
    only member of it's own partition.  Coalescing will attempt to group any
@@ -1086,20 +1087,24 @@ set_var_live_on_entry (tree ssa_name, tr
   if (stmt)
     {
       def_bb = gimple_bb (stmt);
       /* Mark defs in liveout bitmap temporarily.  */
       if (def_bb)
        bitmap_set_bit (&live->liveout[def_bb->index], p);
     }
   else
     def_bb = ENTRY_BLOCK_PTR_FOR_FN (cfun);
 
+  /* An undefined local variable does not need to be very alive.  */
+  if (ssa_undefined_value_p (ssa_name, false))
+    return;
+
   /* Visit each use of SSA_NAME and if it isn't in the same block as the def,
      add it to the list of live on entry blocks.  */
   FOR_EACH_IMM_USE_FAST (use, imm_iter, ssa_name)
     {
       gimple use_stmt = USE_STMT (use);
       basic_block add_block = NULL;
 
       if (gimple_code (use_stmt) == GIMPLE_PHI)
         {
          /* Uses in PHI's are considered to be live at exit of the SRC block
@@ -1422,20 +1427,25 @@ verify_live_on_entry (tree_live_info_p l
                          fprintf (stderr, "\n");
                        }
                      else
                        fprintf (stderr, " and there is no default def.\n");
                    }
                }
            }
          else
            if (d == var)
              {
+               /* An undefined local variable does not need to be very
+                  alive.  */
+               if (ssa_undefined_value_p (var, false))
+                 continue;
+
                /* The only way this var shouldn't be marked live on entry is
                   if it occurs in a PHI argument of the block.  */
                size_t z;
                bool ok = false;
                gimple_stmt_iterator gsi;
                for (gsi = gsi_start_phis (e->dest);
                     !gsi_end_p (gsi) && !ok;
                     gsi_next (&gsi))
                  {
                    gimple phi = gsi_stmt (gsi);
Index: tree-ssa.c
===================================================================
--- tree-ssa.c  (revision 216384)
+++ tree-ssa.c  (working copy)
@@ -1178,24 +1178,25 @@ tree_ssa_useless_type_conversion (tree e
 
 tree
 tree_ssa_strip_useless_type_conversions (tree exp)
 {
   while (tree_ssa_useless_type_conversion (exp))
     exp = TREE_OPERAND (exp, 0);
   return exp;
 }
 
 
-/* Return true if T, an SSA_NAME, has an undefined value.  */
+/* Return true if T, an SSA_NAME, has an undefined value.  PARTIAL is what
+   should be returned if the value is only partially undefined.  */
 
 bool
-ssa_undefined_value_p (tree t)
+ssa_undefined_value_p (tree t, bool partial)
 {
   gimple def_stmt;
   tree var = SSA_NAME_VAR (t);
 
   if (!var)
     ;
   /* Parameters get their initial value from the function entry.  */
   else if (TREE_CODE (var) == PARM_DECL)
     return false;
   /* When returning by reference the return address is actually a hidden
@@ -1205,21 +1206,21 @@ ssa_undefined_value_p (tree t)
   /* Hard register variables get their initial value from the ether.  */
   else if (TREE_CODE (var) == VAR_DECL && DECL_HARD_REGISTER (var))
     return false;
 
   /* The value is undefined iff its definition statement is empty.  */
   def_stmt = SSA_NAME_DEF_STMT (t);
   if (gimple_nop_p (def_stmt))
     return true;
 
   /* Check if the complex was not only partially defined.  */
-  if (is_gimple_assign (def_stmt)
+  if (partial && is_gimple_assign (def_stmt)
       && gimple_assign_rhs_code (def_stmt) == COMPLEX_EXPR)
     {
       tree rhs1, rhs2;
 
       rhs1 = gimple_assign_rhs1 (def_stmt);
       rhs2 = gimple_assign_rhs2 (def_stmt);
       return (TREE_CODE (rhs1) == SSA_NAME && ssa_undefined_value_p (rhs1))
             || (TREE_CODE (rhs2) == SSA_NAME && ssa_undefined_value_p (rhs2));
     }
   return false;
@@ -1551,32 +1552,20 @@ execute_update_addresses_taken (void)
                rhs = gimple_assign_rhs1 (stmt);
                if (gimple_assign_lhs (stmt) != lhs
                    && !useless_type_conversion_p (TREE_TYPE (lhs),
                                                   TREE_TYPE (rhs)))
                  rhs = fold_build1 (VIEW_CONVERT_EXPR,
                                     TREE_TYPE (lhs), rhs);
 
                if (gimple_assign_lhs (stmt) != lhs)
                  gimple_assign_set_lhs (stmt, lhs);
 
-               /* For var ={v} {CLOBBER}; where var lost
-                  TREE_ADDRESSABLE just remove the stmt.  */
-               if (DECL_P (lhs)
-                   && TREE_CLOBBER_P (rhs)
-                   && bitmap_bit_p (suitable_for_renaming, DECL_UID (lhs)))
-                 {
-                   unlink_stmt_vdef (stmt);
-                   gsi_remove (&gsi, true);
-                   release_defs (stmt);
-                   continue;
-                 }
-
                if (gimple_assign_rhs1 (stmt) != rhs)
                  {
                    gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
                    gimple_assign_set_rhs_from_tree (&gsi, rhs);
                  }
              }
 
            else if (gimple_code (stmt) == GIMPLE_CALL)
              {
                unsigned i;
Index: tree-ssa.h
===================================================================
--- tree-ssa.h  (revision 216384)
+++ tree-ssa.h  (working copy)
@@ -44,21 +44,21 @@ extern tree target_for_debug_bind (tree)
 extern void insert_debug_temp_for_var_def (gimple_stmt_iterator *, tree);
 extern void insert_debug_temps_for_defs (gimple_stmt_iterator *);
 extern void reset_debug_uses (gimple);
 extern void release_defs_bitset (bitmap toremove);
 extern void verify_ssa (bool, bool);
 extern void init_tree_ssa (struct function *);
 extern void delete_tree_ssa (void);
 extern bool tree_ssa_useless_type_conversion (tree);
 extern tree tree_ssa_strip_useless_type_conversions (tree);
 
-extern bool ssa_undefined_value_p (tree);
+extern bool ssa_undefined_value_p (tree, bool = true);
 extern void execute_update_addresses_taken (void);
 
 /* Given an edge_var_map V, return the PHI arg definition.  */
 
 static inline tree
 redirect_edge_var_map_def (edge_var_map *v)
 {
   return v->def;
 }
 

Reply via email to