OSDN Git Service

2004-10-27 Daniel Berlin <dberlin@dberlin.org>
authordberlin <dberlin@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 27 Oct 2004 17:45:21 +0000 (17:45 +0000)
committerdberlin <dberlin@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 27 Oct 2004 17:45:21 +0000 (17:45 +0000)
Fix PR tree-optimization/17133

* tree-cfg.c (rewrite_to_new_ssa_names_bb): Also rewrite must
def kill operand.

* tree-flow-inline.h: V_MUST_DEF_OP became V_MUST_DEF_RESULT.
(get_v_must_def_result_ptr): Modify for new structure of
v_must_defs array.
(get_v_must_def_kill_ptr): New.
(op_iter_next_use): Add support for the kill that occurs in V_MUST_DEFs.
(op_iter_next_tree): Ditto. Also V_MAY_DEF_OP became V_MAY_DEF_RESULT.
(op_iter_next_def): V_MAY_DEF_OP became V_MAY_DEF_RESULT.
(op_iter_init): Initialize new mustu members.
(op_iter_next_mustdef): New function.
(op_iter_init_mustdef): Ditto.

* tree-flow.h (rewrite_def_def_chains): New function.

* tree-into-ssa.c (mark_def_sites): Handle mustdefkill operands.
(ssa_mark_def_sites): Ditto.
(rewrite_stmt): Ditto.
(ssa_rewrite_stmt): Ditto.
(rewrite_blocks): Factor out from rewrite_into_ssa.
(mark_def_block_sites): Ditto.
(rewrite_def_def_chains): New function, just rewrites def-def
chains without phi node insertion.

* tree-pass.h (TODO_fix_def_def_chains): New todo flag.

* tree-optimize.c (execute_todo): Handle TODO_fix_def_def_chains.

* tree-pretty-print.c (dump_vops): Print out MUST_DEF's so that
they include the rhs now.

* tree-ssa-ccp.c (visit_assignment): V_MUST_DEF_OP became
V_MUST_DEF_RESULT.

* tree-ssa-dce.c (mark_operand_necessary): Add phionly argument.
Update callers.
(mark_really_necessary_kill_operand_phis): New function.
(perform_tree_ssa_dce): Call it.
(pass_dce): Add TODO_fix_def_def_chains.
(pass_cd_dce): Ditto.

* tree-ssa-loop-im.c (determine_max_movement): Look at kills as
well.
(rewrite_mem_refs): Ditto.

* tree-ssa-loop-manip.c (find_uses_to_rename_stmt): Look at kills
as well.

* tree-ssa-operands.c (allocate_v_may_def_optype):
v_may_def_operand_type_t became v_def_use_operand_type_t.
(allocate_v_must_def_optype) Ditto.
(finalize_ssa_v_must_defs): Update for new operand type, as well
as setting the use portion as well.
(copy_virtual_operands): Copy the kill operand as well.
(create_ssa_artficial_load_stmt): V_MUST_DEF_OP became
V_MUST_DEF_RESULT.

* tree-ssa-operands.h (v_may_def_operand_type): Renamed to
v_def_use_operand_type.
(v_must_def_optype_d): Use v_def_use_operand_type.
(V_MUST_DEF_OP_*): Renamed to V_MUST_DEF_RESULT_*
(V_MUST_DEF_KILL_*): New macros.
(struct ssa_operand_iterator_d): Add num_v_mustu and v_mustu_i
members.
Rename existing must_i and num_v_must members to mustd_i and
num_v_mustd.
(SSA_OP_VMUSTDEFKILL): New flag.
(SSA_OP_VIRTUAL_KILLS): New flag.
(SSA_OP_ALL_OPERANDS): Add in SSA_OP_ALL_KILLS.
(SSA_OP_ALL_KILLS): New flag.
(FOR_EACH_SSA_MUSTDEF_OPERAND): New macro.

* tree-ssa.c (verify_ssa): Verify virtual kills as well.

* tree-vectorizer.c (vect_create_data_ref_ptr): V_MUST_DEF_OP
became V_MUST_DEF_RESULT.
(rename_variables_in_bb): Rename kill pointer as well.

* tree-dfa.c (compute_immediate_uses_for_stmt): Add kills into the
immediate uses.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@89695 138bc75d-0d04-0410-961f-82ee72b054a4

17 files changed:
gcc/ChangeLog
gcc/tree-cfg.c
gcc/tree-dfa.c
gcc/tree-flow-inline.h
gcc/tree-flow.h
gcc/tree-into-ssa.c
gcc/tree-optimize.c
gcc/tree-pass.h
gcc/tree-pretty-print.c
gcc/tree-ssa-ccp.c
gcc/tree-ssa-dce.c
gcc/tree-ssa-loop-im.c
gcc/tree-ssa-loop-manip.c
gcc/tree-ssa-operands.c
gcc/tree-ssa-operands.h
gcc/tree-ssa.c
gcc/tree-vectorizer.c

index 767af3e..75423d8 100644 (file)
@@ -1,3 +1,89 @@
+2004-10-27  Daniel Berlin <dberlin@dberlin.org>
+       
+       Fix PR tree-optimization/17133
+       
+       * tree-cfg.c (rewrite_to_new_ssa_names_bb): Also rewrite must
+       def kill operand.
+
+       * tree-flow-inline.h: V_MUST_DEF_OP became V_MUST_DEF_RESULT.
+       (get_v_must_def_result_ptr): Modify for new structure of
+       v_must_defs array.
+       (get_v_must_def_kill_ptr): New.
+       (op_iter_next_use): Add support for the kill that occurs in V_MUST_DEFs.
+       (op_iter_next_tree): Ditto. Also V_MAY_DEF_OP became V_MAY_DEF_RESULT.
+       (op_iter_next_def): V_MAY_DEF_OP became V_MAY_DEF_RESULT.
+       (op_iter_init): Initialize new mustu members.
+       (op_iter_next_mustdef): New function.
+       (op_iter_init_mustdef): Ditto.
+
+       * tree-flow.h (rewrite_def_def_chains): New function.
+
+       * tree-into-ssa.c (mark_def_sites): Handle mustdefkill operands.
+       (ssa_mark_def_sites): Ditto.
+       (rewrite_stmt): Ditto.
+       (ssa_rewrite_stmt): Ditto.
+       (rewrite_blocks): Factor out from rewrite_into_ssa.
+       (mark_def_block_sites): Ditto.
+       (rewrite_def_def_chains): New function, just rewrites def-def
+       chains without phi node insertion.
+
+       * tree-pass.h (TODO_fix_def_def_chains): New todo flag.
+
+       * tree-optimize.c (execute_todo): Handle TODO_fix_def_def_chains.       
+
+       * tree-pretty-print.c (dump_vops): Print out MUST_DEF's so that
+       they include the rhs now.
+
+       * tree-ssa-ccp.c (visit_assignment): V_MUST_DEF_OP became
+       V_MUST_DEF_RESULT. 
+
+       * tree-ssa-dce.c (mark_operand_necessary): Add phionly argument.
+       Update callers.
+       (mark_really_necessary_kill_operand_phis): New function.
+       (perform_tree_ssa_dce): Call it.
+       (pass_dce): Add TODO_fix_def_def_chains.
+       (pass_cd_dce): Ditto.
+
+       * tree-ssa-loop-im.c (determine_max_movement): Look at kills as
+       well.
+       (rewrite_mem_refs): Ditto.
+
+       * tree-ssa-loop-manip.c (find_uses_to_rename_stmt): Look at kills
+       as well.
+
+       * tree-ssa-operands.c (allocate_v_may_def_optype):
+       v_may_def_operand_type_t became v_def_use_operand_type_t.
+       (allocate_v_must_def_optype) Ditto.
+       (finalize_ssa_v_must_defs): Update for new operand type, as well
+       as setting the use portion as well.
+       (copy_virtual_operands): Copy the kill operand as well.
+       (create_ssa_artficial_load_stmt): V_MUST_DEF_OP became
+       V_MUST_DEF_RESULT. 
+
+       * tree-ssa-operands.h (v_may_def_operand_type): Renamed to
+       v_def_use_operand_type. 
+       (v_must_def_optype_d): Use v_def_use_operand_type.
+       (V_MUST_DEF_OP_*): Renamed to V_MUST_DEF_RESULT_*
+       (V_MUST_DEF_KILL_*): New macros.
+       (struct ssa_operand_iterator_d): Add num_v_mustu and v_mustu_i
+       members.
+       Rename existing must_i and num_v_must members to mustd_i and
+       num_v_mustd. 
+       (SSA_OP_VMUSTDEFKILL): New flag.
+       (SSA_OP_VIRTUAL_KILLS): New flag.
+       (SSA_OP_ALL_OPERANDS): Add in SSA_OP_ALL_KILLS.
+       (SSA_OP_ALL_KILLS): New flag.
+       (FOR_EACH_SSA_MUSTDEF_OPERAND): New macro.
+
+       * tree-ssa.c (verify_ssa): Verify virtual kills as well.
+
+       * tree-vectorizer.c (vect_create_data_ref_ptr): V_MUST_DEF_OP
+       became V_MUST_DEF_RESULT.
+       (rename_variables_in_bb): Rename kill pointer as well.
+
+       * tree-dfa.c (compute_immediate_uses_for_stmt): Add kills into the
+       immediate uses.
+
 2004-10-27  Richard Sandiford  <rsandifo@redhat.com>
 
        * dbxout.c (dbxout_source_line): Move declaration of begin_label to
 2004-10-27  Richard Sandiford  <rsandifo@redhat.com>
 
        * dbxout.c (dbxout_source_line): Move declaration of begin_label to
index af78901..a963124 100644 (file)
@@ -4542,8 +4542,12 @@ rewrite_to_new_ssa_names_bb (basic_block bb, htab_t map)
 
       v_must_defs = V_MUST_DEF_OPS (ann);
       for (i = 0; i < NUM_V_MUST_DEFS (v_must_defs); i++)
 
       v_must_defs = V_MUST_DEF_OPS (ann);
       for (i = 0; i < NUM_V_MUST_DEFS (v_must_defs); i++)
-       rewrite_to_new_ssa_names_def
-               (V_MUST_DEF_OP_PTR (v_must_defs, i), stmt, map);
+       {
+         rewrite_to_new_ssa_names_def
+           (V_MUST_DEF_RESULT_PTR (v_must_defs, i), stmt, map);
+         rewrite_to_new_ssa_names_use
+           (V_MUST_DEF_KILL_PTR (v_must_defs, i),  map);
+       }
     }
 
   FOR_EACH_EDGE (e, ei, bb->succs)
     }
 
   FOR_EACH_EDGE (e, ei, bb->succs)
index cce0ff6..de4e225 100644 (file)
@@ -312,7 +312,14 @@ compute_immediate_uses_for_stmt (tree stmt, int flags, bool (*calc_for)(tree))
          if (!IS_EMPTY_STMT (imm_rdef_stmt) && (!calc_for || calc_for (use)))
            add_immediate_use (imm_rdef_stmt, stmt);
        }
          if (!IS_EMPTY_STMT (imm_rdef_stmt) && (!calc_for || calc_for (use)))
            add_immediate_use (imm_rdef_stmt, stmt);
        }
-    }
+      
+      FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_ALL_KILLS)
+       {
+         tree imm_rdef_stmt = SSA_NAME_DEF_STMT (use);
+         if (!IS_EMPTY_STMT (imm_rdef_stmt) && (!calc_for || calc_for (use)))
+           add_immediate_use (imm_rdef_stmt, stmt);
+       }
+    }  
 }
 
 
 }
 
 
index 0507921..e3c955e 100644 (file)
@@ -267,14 +267,25 @@ get_vuse_op_ptr(vuse_optype vuses, unsigned int index)
   return op;
 }
 
   return op;
 }
 
-/* Return a def_operand_p that is the V_MUST_DEF_OP for the
+/* Return a def_operand_p that is the V_MUST_DEF_RESULT for the
    V_MUST_DEF at INDEX in the V_MUST_DEFS array.  */
 static inline def_operand_p
    V_MUST_DEF at INDEX in the V_MUST_DEFS array.  */
 static inline def_operand_p
-get_v_must_def_op_ptr (v_must_def_optype v_must_defs, unsigned int index)
+get_v_must_def_result_ptr (v_must_def_optype v_must_defs, unsigned int index)
 {
   def_operand_p op;
   gcc_assert (index < v_must_defs->num_v_must_defs);
 {
   def_operand_p op;
   gcc_assert (index < v_must_defs->num_v_must_defs);
-  op.def = &(v_must_defs->v_must_defs[index]);
+  op.def = &(v_must_defs->v_must_defs[index].def);
+  return op;
+}
+
+/* Return a use_operand_p that is the V_MUST_DEF_KILL for the 
+   V_MUST_DEF at INDEX in the V_MUST_DEFS array.  */
+static inline use_operand_p
+get_v_must_def_kill_ptr (v_must_def_optype v_must_defs, unsigned int index)
+{
+  use_operand_p op;
+  gcc_assert (index < v_must_defs->num_v_must_defs);
+  op.use = &(v_must_defs->v_must_defs[index].use);
   return op;
 }
 
   return op;
 }
 
@@ -670,7 +681,12 @@ op_iter_next_use (ssa_op_iter *ptr)
   if (ptr->v_mayu_i < ptr->num_v_mayu)
     {
       return V_MAY_DEF_OP_PTR (ptr->ops->v_may_def_ops,
   if (ptr->v_mayu_i < ptr->num_v_mayu)
     {
       return V_MAY_DEF_OP_PTR (ptr->ops->v_may_def_ops,
-                                      (ptr->v_mayu_i)++);
+                              (ptr->v_mayu_i)++);
+    }
+  if (ptr->v_mustu_i < ptr->num_v_mustu)
+    {
+      return V_MUST_DEF_KILL_PTR (ptr->ops->v_must_def_ops,
+                                 (ptr->v_mustu_i)++);
     }
   ptr->done = true;
   return NULL_USE_OPERAND_P;
     }
   ptr->done = true;
   return NULL_USE_OPERAND_P;
@@ -684,10 +700,10 @@ op_iter_next_def (ssa_op_iter *ptr)
     {
       return DEF_OP_PTR (ptr->ops->def_ops, (ptr->def_i)++);
     }
     {
       return DEF_OP_PTR (ptr->ops->def_ops, (ptr->def_i)++);
     }
-  if (ptr->v_must_i < ptr->num_v_must)
+  if (ptr->v_mustd_i < ptr->num_v_mustd)
     {
     {
-      return V_MUST_DEF_OP_PTR (ptr->ops->v_must_def_ops, 
-                                       (ptr->v_must_i)++);
+      return V_MUST_DEF_RESULT_PTR (ptr->ops->v_must_def_ops, 
+                                       (ptr->v_mustd_i)++);
     }
   if (ptr->v_mayd_i < ptr->num_v_mayd)
     {
     }
   if (ptr->v_mayd_i < ptr->num_v_mayd)
     {
@@ -714,14 +730,18 @@ op_iter_next_tree (ssa_op_iter *ptr)
     {
       return V_MAY_DEF_OP (ptr->ops->v_may_def_ops, (ptr->v_mayu_i)++);
     }
     {
       return V_MAY_DEF_OP (ptr->ops->v_may_def_ops, (ptr->v_mayu_i)++);
     }
+  if (ptr->v_mustu_i < ptr->num_v_mustu)
+    {
+      return V_MUST_DEF_KILL (ptr->ops->v_must_def_ops, (ptr->v_mustu_i)++);
+    }
   if (ptr->def_i < ptr->num_def)
     {
       return DEF_OP (ptr->ops->def_ops, (ptr->def_i)++);
     }
   if (ptr->def_i < ptr->num_def)
     {
       return DEF_OP (ptr->ops->def_ops, (ptr->def_i)++);
     }
-  if (ptr->v_must_i < ptr->num_v_must)
+  if (ptr->v_mustd_i < ptr->num_v_mustd)
     {
     {
-      return V_MUST_DEF_OP (ptr->ops->v_must_def_ops, 
-                                       (ptr->v_must_i)++);
+      return V_MUST_DEF_RESULT (ptr->ops->v_must_def_ops, 
+                                       (ptr->v_mustd_i)++);
     }
   if (ptr->v_mayd_i < ptr->num_v_mayd)
     {
     }
   if (ptr->v_mayd_i < ptr->num_v_mayd)
     {
@@ -749,14 +769,17 @@ op_iter_init (ssa_op_iter *ptr, tree stmt, int flags)
                     ?  NUM_V_MAY_DEFS (ops->v_may_def_ops) : 0;
   ptr->num_v_mayd = (flags & SSA_OP_VMAYDEF) 
                     ?  NUM_V_MAY_DEFS (ops->v_may_def_ops) : 0;
                     ?  NUM_V_MAY_DEFS (ops->v_may_def_ops) : 0;
   ptr->num_v_mayd = (flags & SSA_OP_VMAYDEF) 
                     ?  NUM_V_MAY_DEFS (ops->v_may_def_ops) : 0;
-  ptr->num_v_must = (flags & SSA_OP_VMUSTDEF) 
+  ptr->num_v_mustu = (flags & SSA_OP_VMUSTDEFKILL)
+                     ? NUM_V_MUST_DEFS (ops->v_must_def_ops) : 0;
+  ptr->num_v_mustd = (flags & SSA_OP_VMUSTDEF) 
                     ? NUM_V_MUST_DEFS (ops->v_must_def_ops) : 0;
   ptr->def_i = 0;
   ptr->use_i = 0;
   ptr->vuse_i = 0;
   ptr->v_mayu_i = 0;
   ptr->v_mayd_i = 0;
                     ? NUM_V_MUST_DEFS (ops->v_must_def_ops) : 0;
   ptr->def_i = 0;
   ptr->use_i = 0;
   ptr->vuse_i = 0;
   ptr->v_mayu_i = 0;
   ptr->v_mayd_i = 0;
-  ptr->v_must_i = 0;
+  ptr->v_mustu_i = 0;
+  ptr->v_mustd_i = 0;
 }
 
 /* Initialize iterator PTR to the use operands in STMT based on FLAGS. Return
 }
 
 /* Initialize iterator PTR to the use operands in STMT based on FLAGS. Return
@@ -786,6 +809,25 @@ op_iter_init_tree (ssa_op_iter *ptr, tree stmt, int flags)
   return op_iter_next_tree (ptr);
 }
 
   return op_iter_next_tree (ptr);
 }
 
+/* Get the next iterator mustdef value for PTR, returning the mustdef values in
+   KILL and DEF.  */
+static inline void
+op_iter_next_mustdef (use_operand_p *kill, def_operand_p *def, ssa_op_iter *ptr)
+{
+  if (ptr->v_mustu_i < ptr->num_v_mustu)
+    {
+      *def = V_MUST_DEF_RESULT_PTR (ptr->ops->v_must_def_ops, ptr->v_mustu_i);
+      *kill = V_MUST_DEF_KILL_PTR (ptr->ops->v_must_def_ops, (ptr->v_mustu_i)++);
+      return;
+    }
+  else
+    {
+      *def = NULL_DEF_OPERAND_P;
+      *kill = NULL_USE_OPERAND_P;
+    }
+  ptr->done = true;
+  return;
+}
 /* Get the next iterator maydef value for PTR, returning the maydef values in
    USE and DEF.  */
 static inline void
 /* Get the next iterator maydef value for PTR, returning the maydef values in
    USE and DEF.  */
 static inline void
@@ -815,4 +857,14 @@ op_iter_init_maydef (ssa_op_iter *ptr, tree stmt, use_operand_p *use,
   op_iter_init (ptr, stmt, SSA_OP_VMAYUSE);
   op_iter_next_maydef (use, def, ptr);
 }
   op_iter_init (ptr, stmt, SSA_OP_VMAYUSE);
   op_iter_next_maydef (use, def, ptr);
 }
+
+/* Initialize iterator PTR to the operands in STMT.  Return the first operands
+   in KILL and DEF.  */
+static inline void
+op_iter_init_mustdef (ssa_op_iter *ptr, tree stmt, use_operand_p *kill, 
+                    def_operand_p *def)
+{
+  op_iter_init (ptr, stmt, SSA_OP_VMUSTDEFKILL);
+  op_iter_next_mustdef (kill, def, ptr);
+}
 #endif /* _TREE_FLOW_INLINE_H  */
 #endif /* _TREE_FLOW_INLINE_H  */
index 14b5972..37cf556 100644 (file)
@@ -583,6 +583,7 @@ extern void kill_redundant_phi_nodes (void);
 /* In tree-into-ssa.c  */
 extern void rewrite_into_ssa (bool);
 extern void rewrite_ssa_into_ssa (void);
 /* In tree-into-ssa.c  */
 extern void rewrite_into_ssa (bool);
 extern void rewrite_ssa_into_ssa (void);
+extern void rewrite_def_def_chains (void);
 
 void compute_global_livein (bitmap, bitmap);
 tree duplicate_ssa_name (tree, tree);
 
 void compute_global_livein (bitmap, bitmap);
 tree duplicate_ssa_name (tree, tree);
index 972bec9..079065e 100644 (file)
@@ -379,13 +379,13 @@ mark_def_sites (struct dom_walk_data *walk_data,
   /* If a variable is used before being set, then the variable is live
      across a block boundary, so mark it live-on-entry to BB.  */
 
   /* If a variable is used before being set, then the variable is live
      across a block boundary, so mark it live-on-entry to BB.  */
 
-  FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_USE | SSA_OP_VUSE)
+  FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_USE | SSA_OP_VUSE | SSA_OP_VMUSTDEFKILL)
     {
       if (prepare_use_operand_for_rename (use_p, &uid)
          && !TEST_BIT (kills, uid))
        set_livein_block (USE_FROM_PTR (use_p), bb);
     }
     {
       if (prepare_use_operand_for_rename (use_p, &uid)
          && !TEST_BIT (kills, uid))
        set_livein_block (USE_FROM_PTR (use_p), bb);
     }
-         
+  
   /* Note that virtual definitions are irrelevant for computing KILLS
      because a V_MAY_DEF does not constitute a killing definition of the
      variable.  However, the operand of a virtual definitions is a use
   /* Note that virtual definitions are irrelevant for computing KILLS
      because a V_MAY_DEF does not constitute a killing definition of the
      variable.  However, the operand of a virtual definitions is a use
@@ -438,7 +438,7 @@ ssa_mark_def_sites (struct dom_walk_data *walk_data,
 
   /* If a variable is used before being set, then the variable is live
      across a block boundary, so mark it live-on-entry to BB.  */
 
   /* If a variable is used before being set, then the variable is live
      across a block boundary, so mark it live-on-entry to BB.  */
-  FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_ALL_USES)
+  FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_ALL_USES | SSA_OP_ALL_KILLS)
     {
       uid = SSA_NAME_VERSION (use);
 
     {
       uid = SSA_NAME_VERSION (use);
 
@@ -1077,7 +1077,7 @@ rewrite_stmt (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
   gcc_assert (!ann->modified);
 
   /* Step 1.  Rewrite USES and VUSES in the statement.  */
   gcc_assert (!ann->modified);
 
   /* Step 1.  Rewrite USES and VUSES in the statement.  */
-  FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_ALL_USES)
+  FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_ALL_USES | SSA_OP_ALL_KILLS)
     rewrite_operand (use_p);
 
   /* Step 2.  Register the statement's DEF and VDEF operands.  */
     rewrite_operand (use_p);
 
   /* Step 2.  Register the statement's DEF and VDEF operands.  */
@@ -1121,7 +1121,7 @@ ssa_rewrite_stmt (struct dom_walk_data *walk_data,
   gcc_assert (!ann->modified);
 
   /* Step 1.  Rewrite USES and VUSES in the statement.  */
   gcc_assert (!ann->modified);
 
   /* Step 1.  Rewrite USES and VUSES in the statement.  */
-  FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_ALL_USES)
+  FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_ALL_USES | SSA_OP_ALL_KILLS)
     {
       if (TEST_BIT (names_to_rename, SSA_NAME_VERSION (USE_FROM_PTR (use_p))))
        SET_USE (use_p, get_reaching_def (USE_FROM_PTR (use_p)));
     {
       if (TEST_BIT (names_to_rename, SSA_NAME_VERSION (USE_FROM_PTR (use_p))))
        SET_USE (use_p, get_reaching_def (USE_FROM_PTR (use_p)));
@@ -1382,7 +1382,105 @@ invalidate_name_tags (bitmap vars_to_rename)
       }
 }
 
       }
 }
 
+/* Rewrite the actual blocks, statements, and phi arguments, to be in SSA
+   form.  ADD_PHI_ARGS is true if we should be adding arguments to phi nodes,
+   because they may have been just inserted.  */
+
+static void
+rewrite_blocks (bool add_phi_args)
+{
+  struct dom_walk_data walk_data;
+
+  /* Rewrite all the basic blocks in the program.  */
+  timevar_push (TV_TREE_SSA_REWRITE_BLOCKS);
+
+  /* Setup callbacks for the generic dominator tree walker.  */
+  walk_data.walk_stmts_backward = false;
+  walk_data.dom_direction = CDI_DOMINATORS;
+  walk_data.initialize_block_local_data = NULL;
+  walk_data.before_dom_children_before_stmts = rewrite_initialize_block;
+  walk_data.before_dom_children_walk_stmts = rewrite_stmt;
+  walk_data.before_dom_children_after_stmts = NULL;
+  if (add_phi_args)
+    walk_data.before_dom_children_after_stmts = rewrite_add_phi_arguments; 
+  walk_data.after_dom_children_before_stmts =  NULL;
+  walk_data.after_dom_children_walk_stmts =  NULL;
+  walk_data.after_dom_children_after_stmts =  rewrite_finalize_block;
+  walk_data.global_data = NULL;
+  walk_data.block_local_data_size = 0;
+
+  VARRAY_TREE_INIT (block_defs_stack, 10, "Block DEFS Stack");
+
+  /* Initialize the dominator walker.  */
+  init_walk_dominator_tree (&walk_data);
+
+  /* Recursively walk the dominator tree rewriting each statement in
+     each basic block.  */
+  walk_dominator_tree (&walk_data, ENTRY_BLOCK_PTR);
+
+  /* Finalize the dominator walker.  */
+  fini_walk_dominator_tree (&walk_data);
+
+  htab_delete (def_blocks);
+
+  timevar_pop (TV_TREE_SSA_REWRITE_BLOCKS);
+}
+
+/* Mark the definition site blocks for each variable, so that we know where
+   the variable is actually live.  */
+
+static void 
+mark_def_site_blocks (void)
+{
+  size_t i;
+  struct dom_walk_data walk_data;
+  struct mark_def_sites_global_data mark_def_sites_global_data;
+
+  /* Allocate memory for the DEF_BLOCKS hash table.  */
+  def_blocks = htab_create (VARRAY_ACTIVE_SIZE (referenced_vars),
+                           def_blocks_hash, def_blocks_eq, def_blocks_free);
+
+  for (i = 0; i < num_referenced_vars; i++)
+    set_current_def (referenced_var (i), NULL_TREE);
+
+  /* Ensure that the dominance information is OK.  */
+  calculate_dominance_info (CDI_DOMINATORS);
+
 
 
+  /* Setup callbacks for the generic dominator tree walker to find and
+     mark definition sites.  */
+  walk_data.walk_stmts_backward = false;
+  walk_data.dom_direction = CDI_DOMINATORS;
+  walk_data.initialize_block_local_data = NULL;
+  walk_data.before_dom_children_before_stmts = mark_def_sites_initialize_block;
+  walk_data.before_dom_children_walk_stmts = mark_def_sites;
+  walk_data.before_dom_children_after_stmts = NULL; 
+  walk_data.after_dom_children_before_stmts =  NULL;
+  walk_data.after_dom_children_walk_stmts =  NULL;
+  walk_data.after_dom_children_after_stmts =  NULL;
+
+  /* Notice that this bitmap is indexed using variable UIDs, so it must be
+     large enough to accommodate all the variables referenced in the
+     function, not just the ones we are renaming.  */
+  mark_def_sites_global_data.kills = sbitmap_alloc (num_referenced_vars);
+  walk_data.global_data = &mark_def_sites_global_data;
+
+  /* We do not have any local data.  */
+  walk_data.block_local_data_size = 0;
+
+  /* Initialize the dominator walker.  */
+  init_walk_dominator_tree (&walk_data);
+
+  /* Recursively walk the dominator tree.  */
+  walk_dominator_tree (&walk_data, ENTRY_BLOCK_PTR);
+
+  /* Finalize the dominator walker.  */
+  fini_walk_dominator_tree (&walk_data);
+
+  /* We no longer need this bitmap, clear and free it.  */
+  sbitmap_free (mark_def_sites_global_data.kills);
+
+}
 /* Main entry point into the SSA builder.  The renaming process
    proceeds in five main phases:
 
 /* Main entry point into the SSA builder.  The renaming process
    proceeds in five main phases:
 
@@ -1395,13 +1493,11 @@ invalidate_name_tags (bitmap vars_to_rename)
       order.
 
    3- Find and mark all the blocks that define variables
       order.
 
    3- Find and mark all the blocks that define variables
-      (mark_def_sites).
+      (mark_def_site_blocks).
 
    4- Insert PHI nodes at dominance frontiers (insert_phi_nodes).
 
 
    4- Insert PHI nodes at dominance frontiers (insert_phi_nodes).
 
-   5- Rename all the blocks (rewrite_initialize_block,
-      rewrite_add_phi_arguments) and statements in the program
-      (rewrite_stmt).
+   5- Rename all the blocks (rewrite_blocks) and statements in the program.
 
    Steps 3 and 5 are done using the dominator tree walker
    (walk_dominator_tree).
 
    Steps 3 and 5 are done using the dominator tree walker
    (walk_dominator_tree).
@@ -1414,10 +1510,7 @@ rewrite_into_ssa (bool all)
 {
   bitmap *dfs;
   basic_block bb;
 {
   bitmap *dfs;
   basic_block bb;
-  struct dom_walk_data walk_data;
-  struct mark_def_sites_global_data mark_def_sites_global_data;
   bitmap old_vars_to_rename = vars_to_rename;
   bitmap old_vars_to_rename = vars_to_rename;
-  unsigned i;
   
   timevar_push (TV_TREE_SSA_OTHER);
 
   
   timevar_push (TV_TREE_SSA_OTHER);
 
@@ -1441,9 +1534,7 @@ rewrite_into_ssa (bool all)
       remove_all_phi_nodes_for (vars_to_rename);
     }
 
       remove_all_phi_nodes_for (vars_to_rename);
     }
 
-  /* Allocate memory for the DEF_BLOCKS hash table.  */
-  def_blocks = htab_create (VARRAY_ACTIVE_SIZE (referenced_vars),
-                           def_blocks_hash, def_blocks_eq, def_blocks_free);
+  mark_def_site_blocks ();
 
   /* Initialize dominance frontier and immediate dominator bitmaps. 
      Also count the number of predecessors for each block.  Doing so
 
   /* Initialize dominance frontier and immediate dominator bitmaps. 
      Also count the number of predecessors for each block.  Doing so
@@ -1452,80 +1543,13 @@ rewrite_into_ssa (bool all)
   FOR_EACH_BB (bb)
     dfs[bb->index] = BITMAP_XMALLOC ();
 
   FOR_EACH_BB (bb)
     dfs[bb->index] = BITMAP_XMALLOC ();
 
-  for (i = 0; i < num_referenced_vars; i++)
-    set_current_def (referenced_var (i), NULL_TREE);
-
-  /* Ensure that the dominance information is OK.  */
-  calculate_dominance_info (CDI_DOMINATORS);
-
   /* Compute dominance frontiers.  */
   compute_dominance_frontiers (dfs);
 
   /* Compute dominance frontiers.  */
   compute_dominance_frontiers (dfs);
 
-  /* Setup callbacks for the generic dominator tree walker to find and
-     mark definition sites.  */
-  walk_data.walk_stmts_backward = false;
-  walk_data.dom_direction = CDI_DOMINATORS;
-  walk_data.initialize_block_local_data = NULL;
-  walk_data.before_dom_children_before_stmts = mark_def_sites_initialize_block;
-  walk_data.before_dom_children_walk_stmts = mark_def_sites;
-  walk_data.before_dom_children_after_stmts = NULL; 
-  walk_data.after_dom_children_before_stmts =  NULL;
-  walk_data.after_dom_children_walk_stmts =  NULL;
-  walk_data.after_dom_children_after_stmts =  NULL;
-
-  /* Notice that this bitmap is indexed using variable UIDs, so it must be
-     large enough to accommodate all the variables referenced in the
-     function, not just the ones we are renaming.  */
-  mark_def_sites_global_data.kills = sbitmap_alloc (num_referenced_vars);
-  walk_data.global_data = &mark_def_sites_global_data;
-
-  /* We do not have any local data.  */
-  walk_data.block_local_data_size = 0;
-
-  /* Initialize the dominator walker.  */
-  init_walk_dominator_tree (&walk_data);
-
-  /* Recursively walk the dominator tree.  */
-  walk_dominator_tree (&walk_data, ENTRY_BLOCK_PTR);
-
-  /* Finalize the dominator walker.  */
-  fini_walk_dominator_tree (&walk_data);
-
-  /* We no longer need this bitmap, clear and free it.  */
-  sbitmap_free (mark_def_sites_global_data.kills);
-
   /* Insert PHI nodes at dominance frontiers of definition blocks.  */
   insert_phi_nodes (dfs, NULL);
 
   /* Insert PHI nodes at dominance frontiers of definition blocks.  */
   insert_phi_nodes (dfs, NULL);
 
-  /* Rewrite all the basic blocks in the program.  */
-  timevar_push (TV_TREE_SSA_REWRITE_BLOCKS);
-
-  /* Setup callbacks for the generic dominator tree walker.  */
-  walk_data.walk_stmts_backward = false;
-  walk_data.dom_direction = CDI_DOMINATORS;
-  walk_data.initialize_block_local_data = NULL;
-  walk_data.before_dom_children_before_stmts = rewrite_initialize_block;
-  walk_data.before_dom_children_walk_stmts = rewrite_stmt;
-  walk_data.before_dom_children_after_stmts = rewrite_add_phi_arguments; 
-  walk_data.after_dom_children_before_stmts =  NULL;
-  walk_data.after_dom_children_walk_stmts =  NULL;
-  walk_data.after_dom_children_after_stmts =  rewrite_finalize_block;
-  walk_data.global_data = NULL;
-  walk_data.block_local_data_size = 0;
-
-  VARRAY_TREE_INIT (block_defs_stack, 10, "Block DEFS Stack");
-
-  /* Initialize the dominator walker.  */
-  init_walk_dominator_tree (&walk_data);
-
-  /* Recursively walk the dominator tree rewriting each statement in
-     each basic block.  */
-  walk_dominator_tree (&walk_data, ENTRY_BLOCK_PTR);
-
-  /* Finalize the dominator walker.  */
-  fini_walk_dominator_tree (&walk_data);
-
-  timevar_pop (TV_TREE_SSA_REWRITE_BLOCKS);
+  rewrite_blocks (true);
 
   /* Debugging dumps.  */
   if (dump_file && (dump_flags & TDF_STATS))
 
   /* Debugging dumps.  */
   if (dump_file && (dump_flags & TDF_STATS))
@@ -1539,12 +1563,22 @@ rewrite_into_ssa (bool all)
     BITMAP_XFREE (dfs[bb->index]);
   free (dfs);
 
     BITMAP_XFREE (dfs[bb->index]);
   free (dfs);
 
-  htab_delete (def_blocks);
-
   vars_to_rename = old_vars_to_rename;
   timevar_pop (TV_TREE_SSA_OTHER);
 }
 
   vars_to_rename = old_vars_to_rename;
   timevar_pop (TV_TREE_SSA_OTHER);
 }
 
+/* Rewrite the def-def chains so that they have the correct reaching
+   definitions.  */
+
+void
+rewrite_def_def_chains (void)
+{
+  /* Ensure that the dominance information is OK.  */
+  calculate_dominance_info (CDI_DOMINATORS);
+  mark_def_site_blocks ();
+  rewrite_blocks (false);
+
+}
 /* The marked ssa names may have more than one definition;
    add phi nodes and rewrite them to fix this.  */
 
 /* The marked ssa names may have more than one definition;
    add phi nodes and rewrite them to fix this.  */
 
index fed16c3..88d18a7 100644 (file)
@@ -420,6 +420,11 @@ execute_todo (int properties, unsigned int flags)
       rewrite_into_ssa (false);
       bitmap_clear (vars_to_rename);
     }
       rewrite_into_ssa (false);
       bitmap_clear (vars_to_rename);
     }
+  if (flags & TODO_fix_def_def_chains)
+    {
+      rewrite_def_def_chains ();
+      bitmap_clear (vars_to_rename);
+    }
 
   if ((flags & TODO_dump_func) && dump_file)
     {
 
   if ((flags & TODO_dump_func) && dump_file)
     {
index 6250ae6..7140766 100644 (file)
@@ -106,6 +106,7 @@ struct dump_file_info
 #define TODO_verify_ssa                (1 << 3)
 #define TODO_verify_flow       (1 << 4)
 #define TODO_verify_stmts      (1 << 5)
 #define TODO_verify_ssa                (1 << 3)
 #define TODO_verify_flow       (1 << 4)
 #define TODO_verify_stmts      (1 << 5)
+#define TODO_fix_def_def_chains (1 << 6)        /* rewrite def-def chains  */
 
 #define TODO_verify_all \
   (TODO_verify_ssa | TODO_verify_flow | TODO_verify_stmts)
 
 #define TODO_verify_all \
   (TODO_verify_ssa | TODO_verify_flow | TODO_verify_stmts)
index a473139..3f2d4b6 100644 (file)
@@ -2131,9 +2131,10 @@ newline_and_indent (pretty_printer *buffer, int spc)
 static void
 dump_vops (pretty_printer *buffer, tree stmt, int spc, int flags)
 {
 static void
 dump_vops (pretty_printer *buffer, tree stmt, int spc, int flags)
 {
-  tree use, def;
+  tree use;
   use_operand_p use_p;
   def_operand_p def_p;
   use_operand_p use_p;
   def_operand_p def_p;
+  use_operand_p kill_p;
   ssa_op_iter iter;
 
   FOR_EACH_SSA_MAYDEF_OPERAND (def_p, use_p, stmt, iter)
   ssa_op_iter iter;
 
   FOR_EACH_SSA_MAYDEF_OPERAND (def_p, use_p, stmt, iter)
@@ -2148,10 +2149,14 @@ dump_vops (pretty_printer *buffer, tree stmt, int spc, int flags)
       newline_and_indent (buffer, spc);
     }
 
       newline_and_indent (buffer, spc);
     }
 
-  FOR_EACH_SSA_TREE_OPERAND (def, stmt, iter, SSA_OP_VMUSTDEF)
+  FOR_EACH_SSA_MUSTDEF_OPERAND (def_p, kill_p, stmt, iter)
     {
     {
-      pp_string (buffer, "#   V_MUST_DEF <");
-      dump_generic_node (buffer, def, spc + 2, flags, false);
+      pp_string (buffer, "#   ");
+      dump_generic_node (buffer, DEF_FROM_PTR (def_p),
+                         spc + 2, flags, false);
+      pp_string (buffer, " = V_MUST_DEF <");
+      dump_generic_node (buffer, USE_FROM_PTR (kill_p),
+                         spc + 2, flags, false);
       pp_string (buffer, ">;");
       newline_and_indent (buffer, spc);
     }
       pp_string (buffer, ">;");
       newline_and_indent (buffer, spc);
     }
index 3e8fa7b..b97424f 100644 (file)
@@ -1041,7 +1041,7 @@ visit_assignment (tree stmt, tree *output_p)
     {
       /* If we make it here, then stmt only has one definition:
          a V_MUST_DEF.  */
     {
       /* If we make it here, then stmt only has one definition:
          a V_MUST_DEF.  */
-      lhs = V_MUST_DEF_OP (v_must_defs, 0);
+      lhs = V_MUST_DEF_RESULT (v_must_defs, 0);
     }
 
   if (TREE_CODE (rhs) == SSA_NAME)
     }
 
   if (TREE_CODE (rhs) == SSA_NAME)
index 341b768..2c68861 100644 (file)
@@ -112,7 +112,7 @@ static void find_control_dependence (struct edge_list *, int);
 static inline basic_block find_pdom (basic_block);
 
 static inline void mark_stmt_necessary (tree, bool);
 static inline basic_block find_pdom (basic_block);
 
 static inline void mark_stmt_necessary (tree, bool);
-static inline void mark_operand_necessary (tree);
+static inline void mark_operand_necessary (tree, bool);
 
 static void mark_stmt_if_obviously_necessary (tree, bool);
 static void find_obviously_necessary_stmts (struct edge_list *);
 
 static void mark_stmt_if_obviously_necessary (tree, bool);
 static void find_obviously_necessary_stmts (struct edge_list *);
@@ -234,10 +234,11 @@ mark_stmt_necessary (tree stmt, bool add_to_worklist)
     VARRAY_PUSH_TREE (worklist, stmt);
 }
 
     VARRAY_PUSH_TREE (worklist, stmt);
 }
 
-/* Mark the statement defining operand OP as necessary.  */
+/* Mark the statement defining operand OP as necessary.  PHIONLY is true
+   if we should only mark it necessary if it is a phi node.  */
 
 static inline void
 
 static inline void
-mark_operand_necessary (tree op)
+mark_operand_necessary (tree op, bool phionly)
 {
   tree stmt;
   int ver;
 {
   tree stmt;
   int ver;
@@ -253,7 +254,8 @@ mark_operand_necessary (tree op)
   gcc_assert (stmt);
 
   if (NECESSARY (stmt)
   gcc_assert (stmt);
 
   if (NECESSARY (stmt)
-      || IS_EMPTY_STMT (stmt))
+      || IS_EMPTY_STMT (stmt)
+      || (phionly && TREE_CODE (stmt) != PHI_NODE))
     return;
 
   NECESSARY (stmt) = 1;
     return;
 
   NECESSARY (stmt) = 1;
@@ -592,7 +594,7 @@ propagate_necessity (struct edge_list *el)
             {
              tree arg = PHI_ARG_DEF (i, k);
              if (TREE_CODE (arg) == SSA_NAME)
             {
              tree arg = PHI_ARG_DEF (i, k);
              if (TREE_CODE (arg) == SSA_NAME)
-               mark_operand_necessary (arg);
+               mark_operand_necessary (arg, false);
            }
 
          if (aggressive)
            }
 
          if (aggressive)
@@ -624,11 +626,79 @@ propagate_necessity (struct edge_list *el)
             links).  */
 
          FOR_EACH_SSA_TREE_OPERAND (use, i, iter, SSA_OP_ALL_USES)
             links).  */
 
          FOR_EACH_SSA_TREE_OPERAND (use, i, iter, SSA_OP_ALL_USES)
-           mark_operand_necessary (use);
+           mark_operand_necessary (use, false);
        }
     }
 }
        }
     }
 }
+
+
+/* Propagate necessity around virtual phi nodes used in kill operands.
+   The reason this isn't done during propagate_necessity is because we don't
+   want to keep phis around that are just there for must-defs, unless we
+   absolutely have to.  After we've rewritten the reaching definitions to be
+   correct in the previous part of the fixup routine, we can simply propagate
+   around the information about which of these virtual phi nodes are really
+   used, and set the NECESSARY flag accordingly.
+   Note that we do the minimum here to ensure that we keep alive the phis that
+   are actually used in the corrected SSA form.  In particular, some of these
+   phis may now have all of the same operand, and will be deleted by some
+   other pass.  */
+
+static void
+mark_really_necessary_kill_operand_phis (void)
+{
+  basic_block bb;
+  int i;
+
+  /* Seed the worklist with the new virtual phi arguments and virtual
+     uses */
+  FOR_EACH_BB (bb)
+    {
+      block_stmt_iterator bsi;
+      tree phi;
+      
+      for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
+       {
+         if (!is_gimple_reg (PHI_RESULT (phi)) && NECESSARY (phi))
+           {
+             for (i = 0; i < PHI_NUM_ARGS (phi); i++)
+               mark_operand_necessary (PHI_ARG_DEF (phi, i), true);
+           }
+       }
+      
+      for (bsi = bsi_last (bb); !bsi_end_p (bsi); bsi_prev (&bsi))
+       {
+         tree stmt = bsi_stmt (bsi);
+       
+         if (NECESSARY (stmt))
+           {
+             use_operand_p use_p;
+             ssa_op_iter iter;
+             FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter,
+                                       SSA_OP_VIRTUAL_USES | SSA_OP_VIRTUAL_KILLS)
+               {
+                 tree use = USE_FROM_PTR (use_p);
+                 mark_operand_necessary (use, true);
+               }
+           }
+       }
+    }
+  
+  /* Mark all virtual phis still in use as necessary, and all of their
+     arguments that are phis as necessary.  */
+  while (VARRAY_ACTIVE_SIZE (worklist) > 0)
+    {
+      tree use = VARRAY_TOP_TREE (worklist);
+      VARRAY_POP (worklist);
+      
+      for (i = 0; i < PHI_NUM_ARGS (use); i++)
+       mark_operand_necessary (PHI_ARG_DEF (use, i), true);
+    }
+}
+
+
 \f
 \f
+
 /* Eliminate unnecessary statements. Any instruction not marked as necessary
    contributes nothing to the program, and can be deleted.  */
 
 /* Eliminate unnecessary statements. Any instruction not marked as necessary
    contributes nothing to the program, and can be deleted.  */
 
@@ -640,7 +710,7 @@ eliminate_unnecessary_stmts (void)
 
   if (dump_file && (dump_flags & TDF_DETAILS))
     fprintf (dump_file, "\nEliminating unnecessary statements:\n");
 
   if (dump_file && (dump_flags & TDF_DETAILS))
     fprintf (dump_file, "\nEliminating unnecessary statements:\n");
-
+  
   clear_special_calls ();
   FOR_EACH_BB (bb)
     {
   clear_special_calls ();
   FOR_EACH_BB (bb)
     {
@@ -650,23 +720,23 @@ eliminate_unnecessary_stmts (void)
       /* Remove dead statements.  */
       for (i = bsi_start (bb); ! bsi_end_p (i) ; )
        {
       /* Remove dead statements.  */
       for (i = bsi_start (bb); ! bsi_end_p (i) ; )
        {
-         tree t = bsi_stmt (i);
-
-         stats.total++;
-
-         /* If `i' is not necessary then remove it.  */
-         if (! NECESSARY (t))
-           remove_dead_stmt (&i, bb);
-         else
-           {
-             tree call = get_call_expr_in (t);
-             if (call)
-               notice_special_calls (call);
-             bsi_next (&i);
-           }
+         tree t = bsi_stmt (i);
+
+         stats.total++;
+
+         /* If `i' is not necessary then remove it.  */
+         if (! NECESSARY (t))
+           remove_dead_stmt (&i, bb);
+         else
+           {
+             tree call = get_call_expr_in (t);
+             if (call)
+               notice_special_calls (call);
+             bsi_next (&i);
+           }
        }
     }
        }
     }
-}
+ }
 \f
 /* Remove dead PHI nodes from block BB.  */
 
 \f
 /* Remove dead PHI nodes from block BB.  */
 
@@ -711,6 +781,9 @@ static void
 remove_dead_stmt (block_stmt_iterator *i, basic_block bb)
 {
   tree t = bsi_stmt (*i);
 remove_dead_stmt (block_stmt_iterator *i, basic_block bb)
 {
   tree t = bsi_stmt (*i);
+  def_operand_p def_p;
+
+  ssa_op_iter iter;
 
   if (dump_file && (dump_flags & TDF_DETAILS))
     {
 
   if (dump_file && (dump_flags & TDF_DETAILS))
     {
@@ -765,9 +838,16 @@ remove_dead_stmt (block_stmt_iterator *i, basic_block bb)
       while (EDGE_COUNT (bb->succs) != 1)
         remove_edge (EDGE_SUCC (bb, 1));
     }
       while (EDGE_COUNT (bb->succs) != 1)
         remove_edge (EDGE_SUCC (bb, 1));
     }
-
-  bsi_remove (i);
-  release_defs (t);
+  
+  FOR_EACH_SSA_DEF_OPERAND (def_p, t, iter, 
+                           SSA_OP_VIRTUAL_DEFS | SSA_OP_VIRTUAL_KILLS)
+    {
+      tree def = DEF_FROM_PTR (def_p);
+      bitmap_set_bit (vars_to_rename,
+                     var_ann (SSA_NAME_VAR (def))->uid);
+    }
+  bsi_remove (i);  
+  release_defs (t); 
 }
 \f
 /* Print out removed statement statistics.  */
 }
 \f
 /* Print out removed statement statistics.  */
@@ -875,6 +955,7 @@ perform_tree_ssa_dce (bool aggressive)
 
   propagate_necessity (el);
 
 
   propagate_necessity (el);
 
+  mark_really_necessary_kill_operand_phis ();
   eliminate_unnecessary_stmts ();
 
   if (aggressive)
   eliminate_unnecessary_stmts ();
 
   if (aggressive)
@@ -926,7 +1007,7 @@ struct tree_opt_pass pass_dce =
   0,                                   /* properties_provided */
   0,                                   /* properties_destroyed */
   0,                                   /* todo_flags_start */
   0,                                   /* properties_provided */
   0,                                   /* properties_destroyed */
   0,                                   /* todo_flags_start */
-  TODO_ggc_collect | TODO_verify_ssa,  /* todo_flags_finish */
+  TODO_fix_def_def_chains |TODO_ggc_collect | TODO_verify_ssa, /* todo_flags_finish */
   0                                    /* letter */
 };
 
   0                                    /* letter */
 };
 
@@ -943,7 +1024,7 @@ struct tree_opt_pass pass_cd_dce =
   0,                                   /* properties_provided */
   0,                                   /* properties_destroyed */
   0,                                   /* todo_flags_start */
   0,                                   /* properties_provided */
   0,                                   /* properties_destroyed */
   0,                                   /* todo_flags_start */
-  TODO_ggc_collect | TODO_verify_ssa | TODO_verify_flow,
+  TODO_fix_def_def_chains | TODO_ggc_collect | TODO_verify_ssa | TODO_verify_flow,
                                        /* todo_flags_finish */
   0                                    /* letter */
 };
                                        /* todo_flags_finish */
   0                                    /* letter */
 };
index 27bc1c0..bcdd9d7 100644 (file)
@@ -436,7 +436,7 @@ determine_max_movement (tree stmt, bool must_preserve_exec)
     if (!add_dependency (val, lim_data, loop, true))
       return false;
 
     if (!add_dependency (val, lim_data, loop, true))
       return false;
 
-  FOR_EACH_SSA_TREE_OPERAND (val, stmt, iter, SSA_OP_VIRTUAL_USES)
+  FOR_EACH_SSA_TREE_OPERAND (val, stmt, iter, SSA_OP_VIRTUAL_USES | SSA_OP_VIRTUAL_KILLS)
     if (!add_dependency (val, lim_data, loop, false))
       return false;
 
     if (!add_dependency (val, lim_data, loop, false))
       return false;
 
@@ -1034,8 +1034,7 @@ rewrite_mem_refs (tree tmp_var, struct mem_ref *mem_refs)
 
   for (; mem_refs; mem_refs = mem_refs->next)
     {
 
   for (; mem_refs; mem_refs = mem_refs->next)
     {
-      FOR_EACH_SSA_TREE_OPERAND (var, mem_refs->stmt, iter,
-                                (SSA_OP_VIRTUAL_DEFS | SSA_OP_VUSE))
+      FOR_EACH_SSA_TREE_OPERAND (var, mem_refs->stmt, iter, SSA_OP_ALL_VIRTUALS)
        {
          var = SSA_NAME_VAR (var);
          bitmap_set_bit (vars_to_rename, var_ann (var)->uid);
        {
          var = SSA_NAME_VAR (var);
          bitmap_set_bit (vars_to_rename, var_ann (var)->uid);
index dc4b174..1f949a4 100644 (file)
@@ -254,7 +254,7 @@ find_uses_to_rename_stmt (tree stmt, bitmap *use_blocks)
 
   get_stmt_operands (stmt);
 
 
   get_stmt_operands (stmt);
 
-  FOR_EACH_SSA_TREE_OPERAND (var, stmt, iter, SSA_OP_ALL_USES)
+  FOR_EACH_SSA_TREE_OPERAND (var, stmt, iter, SSA_OP_ALL_USES | SSA_OP_ALL_KILLS)
     find_uses_to_rename_use (bb, var, use_blocks);
 }
 
     find_uses_to_rename_use (bb, var, use_blocks);
 }
 
index 953ef8d..55cebf2 100644 (file)
@@ -174,7 +174,7 @@ allocate_v_may_def_optype (unsigned num)
   v_may_def_optype v_may_def_ops;
   unsigned size;
   size = sizeof (struct v_may_def_optype_d) 
   v_may_def_optype v_may_def_ops;
   unsigned size;
   size = sizeof (struct v_may_def_optype_d) 
-          + sizeof (v_may_def_operand_type_t) * (num - 1);
+          + sizeof (v_def_use_operand_type_t) * (num - 1);
   v_may_def_ops =  ggc_alloc (size);
   v_may_def_ops->num_v_may_defs = num;
   return v_may_def_ops;
   v_may_def_ops =  ggc_alloc (size);
   v_may_def_ops->num_v_may_defs = num;
   return v_may_def_ops;
@@ -202,7 +202,7 @@ allocate_v_must_def_optype (unsigned num)
 {
   v_must_def_optype v_must_def_ops;
   unsigned size;
 {
   v_must_def_optype v_must_def_ops;
   unsigned size;
-  size = sizeof (struct v_must_def_optype_d) + sizeof (tree) * (num - 1);
+  size = sizeof (struct v_must_def_optype_d) + sizeof (v_def_use_operand_type_t) * (num - 1);
   v_must_def_ops =  ggc_alloc (size);
   v_must_def_ops->num_v_must_defs = num;
   return v_must_def_ops;
   v_must_def_ops =  ggc_alloc (size);
   v_must_def_ops->num_v_must_defs = num;
   return v_must_def_ops;
@@ -650,7 +650,7 @@ finalize_ssa_v_must_defs (v_must_def_optype *old_ops_p,
       build_diff = false;
       for (x = 0; x < num; x++)
         {
       build_diff = false;
       for (x = 0; x < num; x++)
         {
-         tree var = old_ops->v_must_defs[x];
+         tree var = old_ops->v_must_defs[x].def;
          if (TREE_CODE (var) == SSA_NAME)
            var = SSA_NAME_VAR (var);
          if (var != VARRAY_TREE (build_v_must_defs, x))
          if (TREE_CODE (var) == SSA_NAME)
            var = SSA_NAME_VAR (var);
          if (var != VARRAY_TREE (build_v_must_defs, x))
@@ -677,17 +677,21 @@ finalize_ssa_v_must_defs (v_must_def_optype *old_ops_p,
          /* Look for VAR in the original vector.  */
          for (i = 0; i < old_num; i++)
            {
          /* Look for VAR in the original vector.  */
          for (i = 0; i < old_num; i++)
            {
-             result = old_ops->v_must_defs[i];
+             result = old_ops->v_must_defs[i].def;
              if (TREE_CODE (result) == SSA_NAME)
                result = SSA_NAME_VAR (result);
              if (result == var)
                {
              if (TREE_CODE (result) == SSA_NAME)
                result = SSA_NAME_VAR (result);
              if (result == var)
                {
-                 v_must_def_ops->v_must_defs[x] = old_ops->v_must_defs[i];
+                 v_must_def_ops->v_must_defs[x].def = old_ops->v_must_defs[i].def;
+                 v_must_def_ops->v_must_defs[x].use = old_ops->v_must_defs[i].use;
                  break;
                }
            }
          if (i == old_num)
                  break;
                }
            }
          if (i == old_num)
-           v_must_def_ops->v_must_defs[x] = var;
+           {
+             v_must_def_ops->v_must_defs[x].def = var;
+             v_must_def_ops->v_must_defs[x].use = var;
+           }
        }
     }
   VARRAY_POP_ALL (build_v_must_defs);
        }
     }
   VARRAY_POP_ALL (build_v_must_defs);
@@ -1672,7 +1676,10 @@ copy_virtual_operands (tree dst, tree src)
     {
       *v_must_defs_new = allocate_v_must_def_optype (NUM_V_MUST_DEFS (v_must_defs));
       for (i = 0; i < NUM_V_MUST_DEFS (v_must_defs); i++)
     {
       *v_must_defs_new = allocate_v_must_def_optype (NUM_V_MUST_DEFS (v_must_defs));
       for (i = 0; i < NUM_V_MUST_DEFS (v_must_defs); i++)
-       SET_V_MUST_DEF_OP (*v_must_defs_new, i, V_MUST_DEF_OP (v_must_defs, i));
+       {
+         SET_V_MUST_DEF_RESULT (*v_must_defs_new, i, V_MUST_DEF_RESULT (v_must_defs, i));
+         SET_V_MUST_DEF_KILL (*v_must_defs_new, i, V_MUST_DEF_KILL (v_must_defs, i));
+       }
     }
 }
 
     }
 }
 
@@ -1701,7 +1708,7 @@ create_ssa_artficial_load_stmt (stmt_operands_p old_ops, tree new_stmt)
   free_vuses (&(ann->operands.vuse_ops));
   free_v_may_defs (&(ann->operands.v_may_def_ops));
   free_v_must_defs (&(ann->operands.v_must_def_ops));
   free_vuses (&(ann->operands.vuse_ops));
   free_v_may_defs (&(ann->operands.v_may_def_ops));
   free_v_must_defs (&(ann->operands.v_must_def_ops));
-
+  
   /* For each VDEF on the original statement, we want to create a
      VUSE of the V_MAY_DEF result or V_MUST_DEF op on the new 
      statement.  */
   /* For each VDEF on the original statement, we want to create a
      VUSE of the V_MAY_DEF result or V_MUST_DEF op on the new 
      statement.  */
@@ -1713,7 +1720,7 @@ create_ssa_artficial_load_stmt (stmt_operands_p old_ops, tree new_stmt)
     
   for (j = 0; j < NUM_V_MUST_DEFS (old_ops->v_must_def_ops); j++)
     {
     
   for (j = 0; j < NUM_V_MUST_DEFS (old_ops->v_must_def_ops); j++)
     {
-      op = V_MUST_DEF_OP (old_ops->v_must_def_ops, j);
+      op = V_MUST_DEF_RESULT (old_ops->v_must_def_ops, j);
       append_vuse (op);
     }
 
       append_vuse (op);
     }
 
index ad0a916..521845f 100644 (file)
@@ -58,17 +58,17 @@ typedef struct use_optype_d GTY(())
 typedef use_optype_t *use_optype;
 
 /* Operand type which stores a def and a use tree.  */
 typedef use_optype_t *use_optype;
 
 /* Operand type which stores a def and a use tree.  */
-typedef struct v_may_def_operand_type GTY(())
+typedef struct v_def_use_operand_type GTY(())
 {
   tree def;
   tree use;
 {
   tree def;
   tree use;
-} v_may_def_operand_type_t;
+} v_def_use_operand_type_t;
 
 /* This represents the MAY_DEFS for a stmt.  */
 typedef struct v_may_def_optype_d GTY(())
 {
   unsigned num_v_may_defs; 
 
 /* This represents the MAY_DEFS for a stmt.  */
 typedef struct v_may_def_optype_d GTY(())
 {
   unsigned num_v_may_defs; 
-  struct v_may_def_operand_type GTY((length ("%h.num_v_may_defs")))
+  struct v_def_use_operand_type GTY((length ("%h.num_v_may_defs")))
                                                              v_may_defs[1];
 } v_may_def_optype_t;
 
                                                              v_may_defs[1];
 } v_may_def_optype_t;
 
@@ -87,7 +87,7 @@ typedef vuse_optype_t *vuse_optype;
 typedef struct v_must_def_optype_d GTY(())
 {
   unsigned num_v_must_defs; 
 typedef struct v_must_def_optype_d GTY(())
 {
   unsigned num_v_must_defs; 
-  tree GTY((length("%h.num_v_must_defs"))) v_must_defs[1];
+  v_def_use_operand_type_t GTY((length("%h.num_v_must_defs"))) v_must_defs[1];
 } v_must_def_optype_t;
 
 typedef v_must_def_optype_t *v_must_def_optype;
 } v_must_def_optype_t;
 
 typedef v_must_def_optype_t *v_must_def_optype;
@@ -157,12 +157,14 @@ typedef stmt_operands_t *stmt_operands_p;
 #define V_MUST_DEF_OPS(ANN)            get_v_must_def_ops (ANN)
 #define STMT_V_MUST_DEF_OPS(STMT)      get_v_must_def_ops (stmt_ann (STMT))
 #define NUM_V_MUST_DEFS(OPS)           ((OPS) ? (OPS)->num_v_must_defs : 0)
 #define V_MUST_DEF_OPS(ANN)            get_v_must_def_ops (ANN)
 #define STMT_V_MUST_DEF_OPS(STMT)      get_v_must_def_ops (stmt_ann (STMT))
 #define NUM_V_MUST_DEFS(OPS)           ((OPS) ? (OPS)->num_v_must_defs : 0)
-#define V_MUST_DEF_OP_PTR(OPS, I)      get_v_must_def_op_ptr ((OPS), (I))
-#define V_MUST_DEF_OP(OPS, I)                                          \
-                               (DEF_FROM_PTR (V_MUST_DEF_OP_PTR ((OPS), (I))))
-#define SET_V_MUST_DEF_OP(OPS, I, V)                                   \
-                               (SET_DEF (V_MUST_DEF_OP_PTR ((OPS), (I)), (V)))
-
+#define V_MUST_DEF_RESULT_PTR(OPS, I)  get_v_must_def_result_ptr ((OPS), (I))
+#define V_MUST_DEF_RESULT(OPS, I) \
+                               (DEF_FROM_PTR (V_MUST_DEF_RESULT_PTR ((OPS), (I))))
+#define SET_V_MUST_DEF_RESULT(OPS, I, V) \
+                               (SET_DEF (V_MUST_DEF_RESULT_PTR ((OPS), (I)), (V)))
+#define V_MUST_DEF_KILL_PTR(OPS, I)  get_v_must_def_kill_ptr ((OPS), (I))
+#define V_MUST_DEF_KILL(OPS, I) (USE_FROM_PTR (V_MUST_DEF_KILL_PTR ((OPS), (I))))
+#define SET_V_MUST_DEF_KILL(OPS, I, V) (SET_USE (V_MUST_DEF_KILL_PTR ((OPS), (I)), (V)))
 
 #define PHI_RESULT_PTR(PHI)    get_phi_result_ptr (PHI)
 #define PHI_RESULT(PHI)                DEF_FROM_PTR (PHI_RESULT_PTR (PHI))
 
 #define PHI_RESULT_PTR(PHI)    get_phi_result_ptr (PHI)
 #define PHI_RESULT(PHI)                DEF_FROM_PTR (PHI_RESULT_PTR (PHI))
@@ -199,13 +201,15 @@ typedef struct ssa_operand_iterator_d
   int num_vuse;
   int num_v_mayu;
   int num_v_mayd;
   int num_vuse;
   int num_v_mayu;
   int num_v_mayd;
-  int num_v_must;
+  int num_v_mustu;
+  int num_v_mustd;
   int use_i;
   int def_i;
   int vuse_i;
   int v_mayu_i;
   int v_mayd_i;
   int use_i;
   int def_i;
   int vuse_i;
   int v_mayu_i;
   int v_mayd_i;
-  int v_must_i;
+  int v_mustu_i;
+  int v_mustd_i;
   stmt_operands_p ops;
   bool done;
 } ssa_op_iter;
   stmt_operands_p ops;
   bool done;
 } ssa_op_iter;
@@ -218,13 +222,17 @@ typedef struct ssa_operand_iterator_d
 #define SSA_OP_VMAYUSE         0x08    /* USE portion of V_MAY_DEFS.  */
 #define SSA_OP_VMAYDEF         0x10    /* DEF portion of V_MAY_DEFS.  */
 #define SSA_OP_VMUSTDEF                0x20    /* V_MUST_DEF definitions.  */
 #define SSA_OP_VMAYUSE         0x08    /* USE portion of V_MAY_DEFS.  */
 #define SSA_OP_VMAYDEF         0x10    /* DEF portion of V_MAY_DEFS.  */
 #define SSA_OP_VMUSTDEF                0x20    /* V_MUST_DEF definitions.  */
+#define SSA_OP_VMUSTDEFKILL     0x40    /* V_MUST_DEF kills.  */
 
 /* These are commonly grouped operand flags.  */
 #define SSA_OP_VIRTUAL_USES    (SSA_OP_VUSE | SSA_OP_VMAYUSE)
 #define SSA_OP_VIRTUAL_DEFS    (SSA_OP_VMAYDEF | SSA_OP_VMUSTDEF)
 
 /* These are commonly grouped operand flags.  */
 #define SSA_OP_VIRTUAL_USES    (SSA_OP_VUSE | SSA_OP_VMAYUSE)
 #define SSA_OP_VIRTUAL_DEFS    (SSA_OP_VMAYDEF | SSA_OP_VMUSTDEF)
+#define SSA_OP_VIRTUAL_KILLS    (SSA_OP_VMUSTDEFKILL)
+#define SSA_OP_ALL_VIRTUALS     (SSA_OP_VIRTUAL_USES | SSA_OP_VIRTUAL_KILLS | SSA_OP_VIRTUAL_DEFS)
 #define SSA_OP_ALL_USES                (SSA_OP_VIRTUAL_USES | SSA_OP_USE)
 #define SSA_OP_ALL_DEFS                (SSA_OP_VIRTUAL_DEFS | SSA_OP_DEF)
 #define SSA_OP_ALL_USES                (SSA_OP_VIRTUAL_USES | SSA_OP_USE)
 #define SSA_OP_ALL_DEFS                (SSA_OP_VIRTUAL_DEFS | SSA_OP_DEF)
-#define SSA_OP_ALL_OPERANDS    (SSA_OP_ALL_USES | SSA_OP_ALL_DEFS)
+#define SSA_OP_ALL_KILLS        (SSA_OP_VIRTUAL_KILLS)
+#define SSA_OP_ALL_OPERANDS    (SSA_OP_ALL_USES | SSA_OP_ALL_DEFS | SSA_OP_ALL_KILLS)
 
 /* This macro executes a loop over the operands of STMT specified in FLAG, 
    returning each operand as a 'tree' in the variable TREEVAR.  ITER is an
 
 /* This macro executes a loop over the operands of STMT specified in FLAG, 
    returning each operand as a 'tree' in the variable TREEVAR.  ITER is an
@@ -258,4 +266,12 @@ typedef struct ssa_operand_iterator_d
        !op_iter_done (&(ITER));                                        \
        op_iter_next_maydef (&(USEVAR), &(DEFVAR), &(ITER)))
 
        !op_iter_done (&(ITER));                                        \
        op_iter_next_maydef (&(USEVAR), &(DEFVAR), &(ITER)))
 
+/* This macro executes a loop over the V_MUST_DEF operands of STMT.  The def
+   and kill for each V_MUST_DEF is returned in DEFVAR and KILLVAR. 
+   ITER is an ssa_op_iter structure used to control the loop.  */
+#define FOR_EACH_SSA_MUSTDEF_OPERAND(DEFVAR, KILLVAR, STMT, ITER)      \
+  for (op_iter_init_mustdef (&(ITER), STMT, &(KILLVAR), &(DEFVAR));    \
+       !op_iter_done (&(ITER));                                        \
+       op_iter_next_mustdef (&(KILLVAR), &(DEFVAR), &(ITER)))
+
 #endif  /* GCC_TREE_SSA_OPERANDS_H  */
 #endif  /* GCC_TREE_SSA_OPERANDS_H  */
index 7f73bcf..d9379ba 100644 (file)
@@ -672,7 +672,7 @@ verify_ssa (void)
        {
          tree stmt = bsi_stmt (bsi);
 
        {
          tree stmt = bsi_stmt (bsi);
 
-         FOR_EACH_SSA_TREE_OPERAND (op, stmt, iter, SSA_OP_VIRTUAL_USES)
+         FOR_EACH_SSA_TREE_OPERAND (op, stmt, iter, SSA_OP_VIRTUAL_USES | SSA_OP_VIRTUAL_KILLS)
            {
              if (verify_use (bb, definition_block[SSA_NAME_VERSION (op)],
                              op, stmt, false, true,
            {
              if (verify_use (bb, definition_block[SSA_NAME_VERSION (op)],
                              op, stmt, false, true,
@@ -1082,7 +1082,8 @@ replace_immediate_uses (tree var, tree repl)
        }
       else
        {
        }
       else
        {
-         FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_VIRTUAL_USES)
+         FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, 
+                                   SSA_OP_VIRTUAL_USES | SSA_OP_VIRTUAL_KILLS)
            if (USE_FROM_PTR (use_p) == var)
              propagate_value (use_p, repl);
        }
            if (USE_FROM_PTR (use_p) == var)
              propagate_value (use_p, repl);
        }
@@ -1464,3 +1465,4 @@ struct tree_opt_pass pass_late_warn_uninitialized =
   0,                                    /* todo_flags_finish */
   0                                    /* letter */
 };
   0,                                    /* todo_flags_finish */
   0                                    /* letter */
 };
+         
index 656c612..df16c2c 100644 (file)
@@ -381,7 +381,10 @@ rename_variables_in_bb (basic_block bb)
 
       v_must_defs = V_MUST_DEF_OPS (ann);
       for (i = 0; i < NUM_V_MUST_DEFS (v_must_defs); i++)
 
       v_must_defs = V_MUST_DEF_OPS (ann);
       for (i = 0; i < NUM_V_MUST_DEFS (v_must_defs); i++)
-       rename_def_op (V_MUST_DEF_OP_PTR (v_must_defs, i), stmt);
+       {
+         rename_use_op (V_MUST_DEF_KILL_PTR (v_must_defs, i));
+         rename_def_op (V_MUST_DEF_RESULT_PTR (v_must_defs, i), stmt);
+       }
     }
 
   FOR_EACH_EDGE (e, ei, bb->succs)
     }
 
   FOR_EACH_EDGE (e, ei, bb->succs)
@@ -1853,7 +1856,7 @@ vect_create_data_ref_ptr (tree stmt, block_stmt_iterator *bsi, tree offset,
     }
   for (i = 0; i < nv_must_defs; i++)
     {
     }
   for (i = 0; i < nv_must_defs; i++)
     {
-      tree def = V_MUST_DEF_OP (v_must_defs, i);
+      tree def = V_MUST_DEF_RESULT (v_must_defs, i);
       if (TREE_CODE (def) == SSA_NAME)
         bitmap_set_bit (vars_to_rename, var_ann (SSA_NAME_VAR (def))->uid);
     }
       if (TREE_CODE (def) == SSA_NAME)
         bitmap_set_bit (vars_to_rename, var_ann (SSA_NAME_VAR (def))->uid);
     }