public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] Splitting of virtual definitions (aka. V_MUST_DEF)
@ 2004-06-07 14:59 Brian Booth
  2004-06-07 18:34 ` Geert Bosch
                   ` (2 more replies)
  0 siblings, 3 replies; 13+ messages in thread
From: Brian Booth @ 2004-06-07 14:59 UTC (permalink / raw)
  To: GCC-Patches; +Cc: Richard Henderson, Diego

[-- Attachment #1: Type: text/plain, Size: 8710 bytes --]

Hi,

At the moment, VDEFs are used to mark statements that either define a
non-GIMPLE register or could possibly define one. This patch splits up
these two cases. It replaces the VDEF with two conceptually different
constructs: V_MAY_DEF and V_MUST_DEF. These definitions are added to
statements that may define a non-GIMPLE register and statements that
have a killing definition of one respectively. Another way of looking at
it is that the V_MAY_DEF is simply VDEF with a new name while V_MUST_DEF
is a VDEF without the implied use of its operand. 

This infrastructure change will make it easier for the compiler to
detect dead stores since a V_MUST_DEF does not have an implied use. For
example, the following:

	struct blah a, b, c;
	...
	a = b;
	a = c;
	...	

would be marked as:

	struct blah a;
	struct blah b;
	struct blah c;
	...
	#   V_MUST_DEF<a_2>
	#   VUSE<b_1>
	a = b;
	#   V_MUST_DEF<a_4>
	#   VUSE<c_3>
	a = c;
	...

And the first statement would be removed by dce. It would also enable
further work on copy propagation of structures.

Bootstrapped and tested on i686-pc-linux-gnu. Bootstrap times are as
follows:

        WITH_PATCH      WITHOUT_PATCH

real    48m24.896s      48m18.499s
user    37m57.030s      37m37.460s
sys     6m10.790s       6m5.690s

There is a slow down of about six seconds but I feel that this can be
overcome with future tuning of the optimization passes to take advantage
of the V_MUST_DEF construct (dse for example).

Brian
---

2004-06-07  Brian Booth  <bbooth@redhat.com>

	* tree-dfa.c (dfa_stats_d): Add num_v_must_defs and rename
	num_vdefs to num_v_may_defs.
	(compute_immediate_uses_for_stmt): Rename occurences of vdef
	to v_may_def.
	(redirect_immediate_uses): Ditto.
	(dump_dfa_stats): Ditto. Also added code to dump 
	num_v_must_defs.
	(collect_dfa_stats_r): Rename occurences of vdef to v_may_def.
	Also add code to sum up the number of v_must_defs.
	(vdefs_disappeared_p): Replace with...
	(v_may_defs_disappeared_p): This.
	(v_must_defs_disappeared_p): New function.
	(mark_new_vars_to_rename): Rename occurences of vdef to 
	v_may_def. Also add code to mark new variables found in 
	V_MUST_DEFs for renameing.
	* tree-flow.h (stmt_ann_d): Add v_must_def_ops and replace
	vdef_ops to v_may_def_ops.
	(get_vdef_ops): Replace with...
	(get_v_may_def_ops): This.
	* tree-flow-inline.h (get_vdef_ops): Replace with...
	(get_v_may_def_ops): This.
	(get_v_must_def_ops): New function.
	(get_vdef_result_ptr): Replace with...
	(get_v_may_def_result_ptr): This.
	(get_vdef_op_ptr): Ditto with...
	(get_v_may_def_op_ptr); This.
	(get_v_must_def_op_ptr): New function.
	* tree-into-ssa.c (mark_def_sites): Rename occurences of vdef
	to v_may_def. Also add code to mark statements with
	V_MUST_DEFs as definition sites.
	(rewrite_stmt): Rename occurences of vdef to v_may_def. Also 
	add code to register new V_MUST_DEFs made by the statement.
	* tree-outof-ssa.c (VIRTUAL_PARTITION): Update comments.
	(check_replaceable): Rename occurences of vdef to v_may_def. 
	Also add check for V_MUST_DEFs.
	(find_replaceable_in_bb): Ditto.
	* tree-pretty-print.c (dump_vops): Rename occurences of vdef
	to v_may_def. Also add code to dump V_MUST_DEFs.
	* tree-sra.c (mark_all_vdefs): Replace with...
	(mark_all_v_may_defs): This.
	(mark_all_v_must_defs): New function.
	(create_scalar_copies): Replace call to mark_all_vdefs with
	calls to mark_all_v_may_defs and mark_all_v_must_defs.
	(scalarize_structures): Rename occurences of vdef to v_may_def. 
	Also add a check for V_MUST_DEFs.
	(scalarize_modify_expr): Rename occurences of vdef to v_may_def.
	* tree-ssa-alias.c (global_var): Update comment.
	(compute_may_aliases): Ditto.
	(compute_points_to_and_addr_escape): Rename occurences of vdef
	to v_may_def. Also add code to mark variables in V_MUST_DEF 
	operands as being written to.
	(group_aliases): Update comment.
	(maybe_create_global_var): Ditto.
	* tree-ssa.c (verify_ssa): Rename occurences of vdef to 
	v_may_def. Also add a check for V_MUST_DEFs on GIMPLE registers.
	(replace_immediate_uses): Rename occurences of vdef to 
	v_may_def.
	* tree-ssa-ccp.c (visit_stmt): Rename occurences of vdef
	to v_may_def. Also add code to mark all V_MUST_DEF operands 
	VARYING.
	(initialize): Ditto.
	(set_rhs): Rename occurences of vdef to v_may_def. Also add
	code to update SSA_NAMEs in V_MUST_DEFs.
	* tree-ssa-copy.c (cprop_into_stmt): Rename occurences of vdef
	to v_may_def.
	* tree-ssa-dce.c (mark_stmt_if_obviously_necessary): Rename 
	occurences of vdef to v_may_def. Also add code to mark 
	statements with V_MUST_DEFs as necessary.
	(propagate_necessity): Rename occurences of vdef to v_may_def.
	* tree-ssa-dom.c (redirect_edges_and_update_ssa_graph): Rename 
	occurences of vdef to v_may_def. Also add code to mark operands
	in V_MUST_DEFs for renaming.
	(eliminate_redundant_computations): Rename occurences of vdef
	to v_may_def.
	(record_equivalences_from_stmt): Rename occurences of vdef
	to v_may_def. Also add code to record VUSEs for V_MUST_DEFs.
	(optimize_stmt): Remove unnesessary variable vdefs. Update
	comment.
	(register_definitions_for_stmt): Rename occurences of vdef
	to v_may_def. Also add code to register definitions made with
	V_MUST_DEFs.
	* tree-ssa-dse.c (fix_stmt_vdefs): Replace with...
	(fix_stmt_v_may_defs): This.
	(fix_phi_uses): Rename occurences of vdef to v_may_def.
	(dse_optimize_stmt): Ditto.
	* tree-ssa-live.c (create_ssa_var_map): Rename occurences of 
	vdef to v_may_def. Also add code to mark V_MUST_DEF operands as 
	being used in virtual operators.
	* tree-ssa-loop.c (mark_defs_for_rewrite): Rename occurences of 
	vdef to v_may_def. Also add code to mark V_MUST_DEF operands for
	renaming.
	* tree-ssa-operands.c (opf_kill_def): New flag for killing 
	definitions.
	(build_vdefs): Renamed to...
	(build_v_may_defs): This.
	(build_v_must_defs): New variable.
	(voperands_d): Add v_must_def_ops and replace vdef_ops with
	v_may_def_ops.
	(append_vdef): Replace with...
	(append_v_may_def): This.
	(append_v_must_def): New function.
	(NUM_FREE): Increment for V_MUST_DEF
	(optype_freelist): Increment its size for V_MUST_DEF
	(allocate_vdef_optype): Replace with...
	(allocate_v_may_def_optype): This.
	(allocate_v_must_def_optype): New function.
	(free_vdefs): Replace with...
	(free_v_may_defs): This.
	(free_v_must_defs): New function.
	(remove_vdefs): Replace with...
	(remove_v_may_defs): This.
	(remove_v_must_defs): New function.
	(init_ssa_operands): Rename occurences of vdef to v_may_def. 
	Also add code to initialize build_v_must_defs.
	(finalize_ssa_vdefs): Replace with...
	(finalize_ssa_v_may_defs): This.
	(finalize_ssa_vuses): Rename occurences of vdef to v_may_def.
	(finalize_ssa_v_must_defs): New function.
	(finalize_ssa_stmt_operands): Replace call to finalize_ssa_vdefs
	with calls to finalize_ssa_v_may_defs and 
	finalize_ssa_v_must_defs.
	(verify_start_operands): Rename occurences of vdef to v_may_def.
	Also add check for build_v_must_defs.
	(get_stmt_operands): Rename occurences of vdef to v_may_def.
	Also add code to handle V_MUST_DEFs and to use opf_kill_def for
	killing definitions.
	(get_expr_operands): Update comment and use opf_kill_def for
	killing definitions.
	(add_stmt_operand): Replace code that appends VDEFs with code
	that appends V_MUST_DEFs when opf_kill_def is set and V_MAY_DEFs
	otherwise.
	(add_call_clobber_ops): Update comments.
	* tree-ssa-operands.h (vdef_optype_d): Replace with...
	(v_may_def_optype_d): This.
	(v_must_def_optype_d): New structure.
	(VDEF_OPS): Replace with...
	(V_MAY_DEF_OPS): This.
	(STMT_VDEF_OPS): Same with...
	(STMT_V_MAY_DEF_OPS): This.
	(NUM_VDEFS): And...
	(NUM_V_MAY_DEFS): This.
	(VDEF_RESULT_PTR): As well as...
	(V_MAY_DEF_RESULT_PTR): This.
	(VDEF_RESULT): Same goes for...
	(V_MAY_DEF_RESULT): This.
	(VDEF_OP_PTR): And...
	(V_MAY_DEF_OP_PTR): This.
	(VDEF_OP): And...
	(V_MAY_DEF_OP): This.
	(V_MUST_DEF_OPS): New macro.
	(STMT_V_MUST_DEF_OPS): Ditto.
	(NUM_V_MUST_DEFS): Ditto.
	(V_MUST_DEF_OP_PTR): Ditto.
	(V_MUST_DEF_OP): Ditto.
	(remove_vdefs): Replace signature with...
	(remove_v_may_defs): This.
	(remove_v_must_defs): New function signature.
	* tree-ssa-pre.c (subst_phis): Replace call to remove_vdefs
	with calls to remove_v_may_defs and remove_v_must_defs.
	(process_left_occs_and_kills): Rename occurences of vdef to 
	v_may_def. Also add code that marks left occurences of operands 
	in V_MUST_DEFs.
	* tree-tailcall.c (find_tail_calls): Rename occurences of vdef 
	to v_may_def. Also add check for V_MUST_DEFs.
	(eliminate_tail_call):Rename occurences of vdef to v_may_def.

testsuite:

	* gcc.dg/tree-ssa/20031015-1.c: Scan for
	V_MAY_DEF instead of VDEF.
	* gcc.dg/tree-ssa/20040517-1.c: Ditto.

[-- Attachment #2: diff.patch --]
[-- Type: text/x-patch, Size: 79979 bytes --]

Index: tree-dfa.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-dfa.c,v
retrieving revision 2.4
diff -c -p -u -p -r2.4 tree-dfa.c
--- tree-dfa.c	15 May 2004 23:07:51 -0000	2.4
+++ tree-dfa.c	27 May 2004 18:32:54 -0000
@@ -59,8 +59,9 @@ struct dfa_stats_d
   long num_phis;
   long num_phi_args;
   int max_num_phi_args;
-  long num_vdefs;
+  long num_v_may_defs;
   long num_vuses;
+  long num_v_must_defs;
 };
 
 
@@ -280,7 +281,7 @@ compute_immediate_uses_for_stmt (tree st
   size_t i;
   use_optype uses;
   vuse_optype vuses;
-  vdef_optype vdefs;
+  v_may_def_optype v_may_defs;
   stmt_ann_t ann;
 
 #ifdef ENABLE_CHECKING
@@ -314,10 +315,10 @@ compute_immediate_uses_for_stmt (tree st
 	    add_immediate_use (imm_rdef_stmt, stmt);
 	}
 
-      vdefs = VDEF_OPS (ann);
-      for (i = 0; i < NUM_VDEFS (vdefs); i++)
+      v_may_defs = V_MAY_DEF_OPS (ann);
+      for (i = 0; i < NUM_V_MAY_DEFS (v_may_defs); i++)
 	{
-	  tree vuse = VDEF_OP (vdefs, i);
+	  tree vuse = V_MAY_DEF_OP (v_may_defs, i);
 	  tree imm_rdef_stmt = SSA_NAME_DEF_STMT (vuse);
 	  if (!IS_EMPTY_STMT (imm_rdef_stmt) && (!calc_for || calc_for (vuse)))
 	    add_immediate_use (imm_rdef_stmt, stmt);
@@ -390,7 +391,7 @@ redirect_immediate_uses (tree old, tree 
   stmt_ann_t ann = get_stmt_ann (old);
   use_optype uses = USE_OPS (ann);
   vuse_optype vuses = VUSE_OPS (ann);
-  vdef_optype vdefs = VDEF_OPS (ann);
+  v_may_def_optype v_may_defs = V_MAY_DEF_OPS (ann);
   unsigned int i;
 
   /* Look at USE_OPS or VUSE_OPS according to FLAGS.  */
@@ -400,8 +401,8 @@ redirect_immediate_uses (tree old, tree 
   for (i = 0; i < NUM_VUSES (vuses); i++)
     redirect_immediate_use (VUSE_OP (vuses, i), old, new);
 
-  for (i = 0; i < NUM_VDEFS (vdefs); i++)
-    redirect_immediate_use (VDEF_OP (vdefs, i), old, new);
+  for (i = 0; i < NUM_V_MAY_DEFS (v_may_defs); i++)
+    redirect_immediate_use (V_MAY_DEF_OP (v_may_defs, i), old, new);
 }
 
 
@@ -723,9 +724,14 @@ dump_dfa_stats (FILE *file)
   fprintf (file, fmt_str_1, "VUSE operands", dfa_stats.num_vuses,
 	   SCALE (size), LABEL (size));
 
-  size = dfa_stats.num_vdefs * sizeof (tree *);
+  size = dfa_stats.num_v_may_defs * sizeof (tree *);
   total += size;
-  fprintf (file, fmt_str_1, "VDEF operands", dfa_stats.num_vdefs,
+  fprintf (file, fmt_str_1, "V_MAY_DEF operands", dfa_stats.num_v_may_defs,
+	   SCALE (size), LABEL (size));
+	   
+  size = dfa_stats.num_v_must_defs * sizeof (tree *);
+  total += size;
+  fprintf (file, fmt_str_1, "V_MUST_DEF operands", dfa_stats.num_v_must_defs,
 	   SCALE (size), LABEL (size));
 
   size = dfa_stats.num_phis * sizeof (struct tree_phi_node);
@@ -821,8 +827,9 @@ collect_dfa_stats_r (tree *tp, int *walk
 	    dfa_stats_p->num_stmt_anns++;
 	    dfa_stats_p->num_defs += NUM_DEFS (DEF_OPS (ann));
 	    dfa_stats_p->num_uses += NUM_USES (USE_OPS (ann));
-	    dfa_stats_p->num_vdefs += NUM_VDEFS (VDEF_OPS (ann));
+	    dfa_stats_p->num_v_may_defs += NUM_V_MAY_DEFS (V_MAY_DEF_OPS (ann));
 	    dfa_stats_p->num_vuses += NUM_VUSES (VUSE_OPS (ann));
+	    dfa_stats_p->num_v_must_defs += NUM_V_MUST_DEFS (V_MUST_DEF_OPS (ann));
 	    break;
 	  }
 
@@ -1036,21 +1043,39 @@ add_referenced_tmp_var (tree var)
   add_referenced_var (var, NULL);
 }
 
+/* Return true if V_MAY_DEFS_AFTER contains fewer entries than V_MAY_DEFS_BEFORE.
+   Note that this assumes that both varrays are V_MAY_DEF operands for the same
+   statement.  */
+
+static inline bool
+v_may_defs_disappeared_p (v_may_def_optype v_may_defs_before, v_may_def_optype v_may_defs_after)
+{
+  /* If there was nothing before, nothing could've disappeared.  */
+  if (v_may_defs_before == NULL)
+    return false;
+     
+  /* All/some of them gone.  */
+  if (v_may_defs_after == NULL
+      || NUM_V_MAY_DEFS (v_may_defs_before) > NUM_V_MAY_DEFS (v_may_defs_after))
+    return true;
+
+  return false;
+}
 
-/* Return true if VDEFS_AFTER contains fewer entries than VDEFS_BEFORE.
-   Note that this assumes that both varrays are VDEF operands for the same
+/* Return true if V_MUST_DEFS_AFTER contains fewer entries than V_MUST_DEFS_BEFORE.
+   Note that this assumes that both varrays are V_MUST_DEF operands for the same
    statement.  */
 
 static inline bool
-vdefs_disappeared_p (vdef_optype vdefs_before, vdef_optype vdefs_after)
+v_must_defs_disappeared_p (v_must_def_optype v_must_defs_before, v_must_def_optype v_must_defs_after)
 {
   /* If there was nothing before, nothing could've disappeared.  */
-  if (vdefs_before == NULL)
+  if (v_must_defs_before == NULL)
     return false;
      
   /* All/some of them gone.  */
-  if (vdefs_after == NULL
-      || NUM_VDEFS (vdefs_before) > NUM_VDEFS (vdefs_after))
+  if (v_must_defs_after == NULL
+      || NUM_V_MUST_DEFS (v_must_defs_before) > NUM_V_MUST_DEFS (v_must_defs_after))
     return true;
 
   return false;
@@ -1065,12 +1090,14 @@ mark_new_vars_to_rename (tree stmt, bitm
 {
   def_optype defs;
   use_optype uses;
-  vdef_optype vdefs;
+  v_may_def_optype v_may_defs;
   vuse_optype vuses;
+  v_must_def_optype v_must_defs;
   size_t i;
   bitmap vars_in_vops_to_rename;
   bool found_exposed_symbol = false;
-  vdef_optype vdefs_before, vdefs_after;
+  v_may_def_optype v_may_defs_before, v_may_defs_after;
+  v_must_def_optype v_must_defs_before, v_must_defs_after;
   stmt_ann_t ann;
 
   vars_in_vops_to_rename = BITMAP_XMALLOC ();
@@ -1085,10 +1112,10 @@ mark_new_vars_to_rename (tree stmt, bitm
      rename them if there are not any newly exposed symbols in the
      statement operands.  */
   ann = stmt_ann (stmt);
-  vdefs_before = vdefs = VDEF_OPS (ann);
-  for (i = 0; i < NUM_VDEFS (vdefs); i++)
+  v_may_defs_before = v_may_defs = V_MAY_DEF_OPS (ann);
+  for (i = 0; i < NUM_V_MAY_DEFS (v_may_defs); i++)
     {
-      tree var = VDEF_RESULT (vdefs, i);
+      tree var = V_MAY_DEF_RESULT (v_may_defs, i);
       if (!DECL_P (var))
 	var = SSA_NAME_VAR (var);
       bitmap_set_bit (vars_in_vops_to_rename, var_ann (var)->uid);
@@ -1103,6 +1130,15 @@ mark_new_vars_to_rename (tree stmt, bitm
       bitmap_set_bit (vars_in_vops_to_rename, var_ann (var)->uid);
     }
 
+  v_must_defs_before = v_must_defs = V_MUST_DEF_OPS (ann);
+  for (i = 0; i < NUM_V_MUST_DEFS (v_must_defs); i++)
+    {
+      tree var = V_MUST_DEF_OP (v_must_defs, i);
+      if (!DECL_P (var))
+	var = SSA_NAME_VAR (var);
+      bitmap_set_bit (vars_in_vops_to_rename, var_ann (var)->uid);
+    }
+
   /* Now force an operand re-scan on the statement and mark any newly
      exposed variables.  */
   modify_stmt (stmt);
@@ -1130,10 +1166,10 @@ mark_new_vars_to_rename (tree stmt, bitm
 	}
     }
 
-  vdefs_after = vdefs = VDEF_OPS (ann);
-  for (i = 0; i < NUM_VDEFS (vdefs); i++)
+  v_may_defs_after = v_may_defs = V_MAY_DEF_OPS (ann);
+  for (i = 0; i < NUM_V_MAY_DEFS (v_may_defs); i++)
     {
-      tree var = VDEF_RESULT (vdefs, i);
+      tree var = V_MAY_DEF_RESULT (v_may_defs, i);
       if (DECL_P (var))
 	{
 	  found_exposed_symbol = true;
@@ -1151,6 +1187,17 @@ mark_new_vars_to_rename (tree stmt, bitm
 	  bitmap_set_bit (vars_to_rename, var_ann (var)->uid);
 	}
     }
+    
+  v_must_defs_after = v_must_defs = V_MUST_DEF_OPS (ann);
+  for (i = 0; i < NUM_V_MUST_DEFS (v_must_defs); i++)
+    {
+      tree var = V_MUST_DEF_OP (v_must_defs, i);
+      if (DECL_P (var))
+	{
+	  found_exposed_symbol = true;
+	  bitmap_set_bit (vars_to_rename, var_ann (var)->uid);
+	}
+    }  
 
   /* If we found any newly exposed symbols, or if there are fewer VDEF
      operands in the statement, add the variables we had set in
@@ -1158,7 +1205,8 @@ mark_new_vars_to_rename (tree stmt, bitm
      vanishing VDEFs because in those cases, the names that were formerly
      generated by this statement are not going to be available anymore.  */
   if (found_exposed_symbol
-      || vdefs_disappeared_p (vdefs_before, vdefs_after))
+      || v_may_defs_disappeared_p (v_may_defs_before, v_may_defs_after)
+      || v_must_defs_disappeared_p (v_must_defs_before, v_must_defs_after))
     bitmap_a_or_b (vars_to_rename, vars_to_rename, vars_in_vops_to_rename);
 
   BITMAP_XFREE (vars_in_vops_to_rename);
Index: tree-flow.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-flow.h,v
retrieving revision 2.4
diff -c -p -u -p -r2.4 tree-flow.h
--- tree-flow.h	18 May 2004 02:53:55 -0000	2.4
+++ tree-flow.h	27 May 2004 18:32:54 -0000
@@ -238,9 +238,10 @@ struct stmt_ann_d GTY(())
   struct def_optype_d * GTY (()) def_ops;
   struct use_optype_d * GTY (()) use_ops;
 
-  /* Virtual operands (VDEF and VUSE).  */
-  struct vdef_optype_d * GTY (()) vdef_ops;
+  /* Virtual operands (V_MAY_DEF, VUSE, and V_MUST_DEF).  */
+  struct v_may_def_optype_d * GTY (()) v_may_def_ops;
   struct vuse_optype_d * GTY (()) vuse_ops;
+  struct v_must_def_optype_d * GTY (()) v_must_def_ops;
 
   /* Dataflow information.  */
   dataflow_t df;
@@ -310,7 +311,7 @@ static inline int get_lineno (tree);
 static inline const char *get_filename (tree);
 static inline bool is_exec_stmt (tree);
 static inline bool is_label_stmt (tree);
-static inline vdef_optype get_vdef_ops (stmt_ann_t);
+static inline v_may_def_optype get_v_may_def_ops (stmt_ann_t);
 static inline vuse_optype get_vuse_ops (stmt_ann_t);
 static inline use_optype get_use_ops (stmt_ann_t);
 static inline def_optype get_def_ops (stmt_ann_t);
Index: tree-flow-inline.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-flow-inline.h,v
retrieving revision 2.2
diff -c -p -u -p -r2.2 tree-flow-inline.h
--- tree-flow-inline.h	21 May 2004 15:24:54 -0000	2.2
+++ tree-flow-inline.h	27 May 2004 18:32:54 -0000
@@ -193,10 +193,10 @@ get_use_ops (stmt_ann_t ann)
   return ann ? ann->use_ops : NULL;
 }
 
-static inline vdef_optype
-get_vdef_ops (stmt_ann_t ann)
+static inline v_may_def_optype
+get_v_may_def_ops (stmt_ann_t ann)
 {
-  return ann ? ann->vdef_ops : NULL;
+  return ann ? ann->v_may_def_ops : NULL;
 }
 
 static inline vuse_optype
@@ -205,6 +205,12 @@ get_vuse_ops (stmt_ann_t ann)
   return ann ? ann->vuse_ops : NULL;
 }
 
+static inline v_must_def_optype
+get_v_must_def_ops (stmt_ann_t ann)
+{
+  return ann ? ann->v_must_def_ops : NULL;
+}
+
 static inline tree *
 get_use_op_ptr (use_optype uses, unsigned int index)
 {
@@ -226,23 +232,23 @@ get_def_op_ptr (def_optype defs, unsigne
 }
 
 static inline tree *
-get_vdef_result_ptr(vdef_optype vdefs, unsigned int index)
+get_v_may_def_result_ptr(v_may_def_optype v_may_defs, unsigned int index)
 {
 #ifdef ENABLE_CHECKING
-  if (index >= vdefs->num_vdefs)
+  if (index >= v_may_defs->num_v_may_defs)
     abort();
 #endif
-  return &(vdefs->vdefs[index * 2]);
+  return &(v_may_defs->v_may_defs[index * 2]);
 }
 
 static inline tree *
-get_vdef_op_ptr(vdef_optype vdefs, unsigned int index)
+get_v_may_def_op_ptr(v_may_def_optype v_may_defs, unsigned int index)
 {
 #ifdef ENABLE_CHECKING
-  if (index >= vdefs->num_vdefs)
+  if (index >= v_may_defs->num_v_may_defs)
     abort();
 #endif
-  return &(vdefs->vdefs[index * 2 + 1]);
+  return &(v_may_defs->v_may_defs[index * 2 + 1]);
 }
 
 static inline tree *
@@ -255,6 +261,16 @@ get_vuse_op_ptr(vuse_optype vuses, unsig
   return &(vuses->vuses[index]);
 }
 
+static inline tree *
+get_v_must_def_op_ptr (v_must_def_optype v_must_defs, unsigned int index)
+{
+#ifdef ENABLE_CHECKING
+  if (index >= v_must_defs->num_v_must_defs)
+    abort();
+#endif
+  return &(v_must_defs->v_must_defs[index]);
+}
+
 static inline void
 start_ssa_stmt_operands (tree stmt ATTRIBUTE_UNUSED)
 {
Index: tree-into-ssa.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-into-ssa.c,v
retrieving revision 2.7
diff -c -p -u -p -r2.7 tree-into-ssa.c
--- tree-into-ssa.c	19 May 2004 20:44:32 -0000	2.7
+++ tree-into-ssa.c	27 May 2004 18:32:54 -0000
@@ -211,7 +211,8 @@ mark_def_sites (struct dom_walk_data *wa
 {
   struct mark_def_sites_global_data *gd = walk_data->global_data;
   sbitmap kills = gd->kills;
-  vdef_optype vdefs;
+  v_may_def_optype v_may_defs;
+  v_must_def_optype v_must_defs;
   vuse_optype vuses;
   def_optype defs;
   use_optype uses;
@@ -248,22 +249,35 @@ mark_def_sites (struct dom_walk_data *wa
     }
 
   /* Note that virtual definitions are irrelevant for computing KILLS
-     because a VDEF does not constitute a killing definition of the
+     because a V_MAY_DEF does not constitute a killing definition of the
      variable.  However, the operand of a virtual definitions is a use
      of the variable, so it may cause the variable to be considered
      live-on-entry.  */
-  vdefs = VDEF_OPS (ann);
-  for (i = 0; i < NUM_VDEFS (vdefs); i++)
+  v_may_defs = V_MAY_DEF_OPS (ann);
+  for (i = 0; i < NUM_V_MAY_DEFS (v_may_defs); i++)
     {
-      if (prepare_operand_for_rename (VDEF_OP_PTR (vdefs, i), &uid, true))
+      if (prepare_operand_for_rename (V_MAY_DEF_OP_PTR (v_may_defs, i), &uid, true))
 	{
 	  /* If we do not already have an SSA_NAME for our destination,
 	     then set the destination to the source.  */
-	  if (TREE_CODE (VDEF_RESULT (vdefs, i)) != SSA_NAME)
-	    VDEF_RESULT (vdefs, i) = VDEF_OP (vdefs, i);
+	  if (TREE_CODE (V_MAY_DEF_RESULT (v_may_defs, i)) != SSA_NAME)
+	    V_MAY_DEF_RESULT (v_may_defs, i) = V_MAY_DEF_OP (v_may_defs, i);
+	    
+          set_livein_block (V_MAY_DEF_OP (v_may_defs, i), bb);
+	  set_def_block (V_MAY_DEF_RESULT (v_may_defs, i), bb);
+	}
+    }
+
+  /* Now process the virtual must-defs made by this statement.  */
+  v_must_defs = V_MUST_DEF_OPS (ann);
+  for (i = 0; i < NUM_V_MUST_DEFS (v_must_defs); i++)
+    {
+      tree *def_p = V_MUST_DEF_OP_PTR (v_must_defs, i);
 
-	  set_livein_block (VDEF_OP (vdefs, i), bb);
-	  set_def_block (VDEF_RESULT (vdefs, i), bb);
+      if (prepare_operand_for_rename (def_p, &uid, false))
+	{
+	  set_def_block (*def_p, bb);
+	  SET_BIT (kills, uid);
 	}
     }
 
@@ -717,7 +731,8 @@ rewrite_stmt (struct dom_walk_data *walk
   stmt_ann_t ann;
   tree stmt;
   vuse_optype vuses;
-  vdef_optype vdefs;
+  v_may_def_optype v_may_defs;
+  v_must_def_optype v_must_defs;
   def_optype defs;
   use_optype uses;
   struct rewrite_block_data *bd;
@@ -744,7 +759,8 @@ rewrite_stmt (struct dom_walk_data *walk
   defs = DEF_OPS (ann);
   uses = USE_OPS (ann);
   vuses = VUSE_OPS (ann);
-  vdefs = VDEF_OPS (ann);
+  v_may_defs = V_MAY_DEF_OPS (ann);
+  v_must_defs = V_MUST_DEF_OPS (ann);
 
   /* Step 1.  Rewrite USES and VUSES in the statement.  */
   for (i = 0; i < NUM_USES (uses); i++)
@@ -768,18 +784,32 @@ rewrite_stmt (struct dom_walk_data *walk
     }
 
   /* Register new virtual definitions made by the statement.  */
-  for (i = 0; i < NUM_VDEFS (vdefs); i++)
+  for (i = 0; i < NUM_V_MAY_DEFS (v_may_defs); i++)
     {
-      rewrite_operand (VDEF_OP_PTR (vdefs, i));
+      rewrite_operand (V_MAY_DEF_OP_PTR (v_may_defs, i));
 
-      if (TREE_CODE (VDEF_RESULT (vdefs, i)) != SSA_NAME)
-	*VDEF_RESULT_PTR (vdefs, i)
-	  = make_ssa_name (VDEF_RESULT (vdefs, i), stmt);
+      if (TREE_CODE (V_MAY_DEF_RESULT (v_may_defs, i)) != SSA_NAME)
+	*V_MAY_DEF_RESULT_PTR (v_may_defs, i)
+	  = make_ssa_name (V_MAY_DEF_RESULT (v_may_defs, i), stmt);
 
       /* FIXME: We shouldn't be registering new defs if the variable
 	 doesn't need to be renamed.  */
-      register_new_def (VDEF_RESULT (vdefs, i), &bd->block_defs);
+      register_new_def (V_MAY_DEF_RESULT (v_may_defs, i), &bd->block_defs);
+    }
+        
+  /* Register new virtual mustdefs made by the statement.  */
+  for (i = 0; i < NUM_V_MUST_DEFS (v_must_defs); i++)
+    {
+      tree *v_must_def_p = V_MUST_DEF_OP_PTR (v_must_defs, i);
+
+      if (TREE_CODE (*v_must_def_p) != SSA_NAME)
+	*v_must_def_p = make_ssa_name (*v_must_def_p, stmt);
+
+      /* FIXME: We shouldn't be registering new mustdefs if the variable
+	 doesn't need to be renamed.  */
+      register_new_def (*v_must_def_p, &bd->block_defs);
     }
+    
 }
 
 
Index: tree-outof-ssa.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-outof-ssa.c,v
retrieving revision 2.3
diff -c -p -u -p -r2.3 tree-outof-ssa.c
--- tree-outof-ssa.c	14 May 2004 02:29:22 -0000	2.3
+++ tree-outof-ssa.c	27 May 2004 18:32:54 -0000
@@ -1134,7 +1134,7 @@ coalesce_vars (var_map map, tree_live_in
    dependent on any virtual variable (via a VUSE) has a dependence added
    to the special partition defined by VIRTUAL_PARTITION.
 
-   Whenever a VDEF is seen, all expressions dependent this VIRTUAL_PARTITION
+   Whenever a V_MAY_DEF is seen, all expressions dependent this VIRTUAL_PARTITION
    are removed from consideration.
 
    At the end of a basic block, all expression are removed from consideration
@@ -1171,7 +1171,7 @@ typedef struct temp_expr_table_d 
   value_expr_p pending_dependence;
 } *temp_expr_table_p;
 
-/* Used to indicate a dependancy on VDEFs.  */
+/* Used to indicate a dependancy on V_MAY_DEFs.  */
 #define VIRTUAL_PARTITION(table)	(table->virtual_partition)
 
 static temp_expr_table_p new_temp_expr_table (var_map);
@@ -1437,8 +1437,12 @@ check_replaceable (temp_expr_table_p tab
   if (DECL_HARD_REGISTER (SSA_NAME_VAR (def)))
     return false;
 
-  /* There must be no VDEFS.  */
-  if (NUM_VDEFS (VDEF_OPS (ann)) != 0)
+  /* There must be no V_MAY_DEFS.  */
+  if (NUM_V_MAY_DEFS (V_MAY_DEF_OPS (ann)) != 0)
+    return false;
+
+  /* There must be no V_MUST_DEFS.  */
+  if (NUM_V_MUST_DEFS (V_MUST_DEF_OPS (ann)) != 0)
     return false;
 
   /* Float expressions must go through memory if float-store is on.  */
@@ -1646,8 +1650,12 @@ find_replaceable_in_bb (temp_expr_table_
 	  free_value_expr (tab, p);
 	}
 
-      /* A VDEF kills any expression using a virtual operand.  */
-      if (NUM_VDEFS (VDEF_OPS (ann)) > 0)
+      /* A V_MAY_DEF kills any expression using a virtual operand.  */
+      if (NUM_V_MAY_DEFS (V_MAY_DEF_OPS (ann)) > 0)
+        kill_virtual_exprs (tab, true);
+	
+      /* A V_MUST_DEF kills any expression using a virtual operand.  */
+      if (NUM_V_MUST_DEFS (V_MUST_DEF_OPS (ann)) > 0)
         kill_virtual_exprs (tab, true);
     }
 }
Index: tree-pretty-print.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-pretty-print.c,v
retrieving revision 2.2
diff -c -p -u -p -r2.2 tree-pretty-print.c
--- tree-pretty-print.c	15 May 2004 23:07:52 -0000	2.2
+++ tree-pretty-print.c	27 May 2004 18:32:54 -0000
@@ -2045,15 +2045,25 @@ dump_vops (pretty_printer *buffer, tree 
 {
   size_t i;
   stmt_ann_t ann = stmt_ann (stmt);
-  vdef_optype vdefs = VDEF_OPS (ann);
+  v_may_def_optype v_may_defs = V_MAY_DEF_OPS (ann);
+  v_must_def_optype v_must_defs = V_MUST_DEF_OPS (ann);
   vuse_optype vuses = VUSE_OPS (ann);
 
-  for (i = 0; i < NUM_VDEFS (vdefs); i++)
+  for (i = 0; i < NUM_V_MAY_DEFS (v_may_defs); i++)
     {
       pp_string (buffer, "#   ");
-      dump_generic_node (buffer, VDEF_RESULT (vdefs, i), spc + 2, flags, false);
-      pp_string (buffer, " = VDEF <");
-      dump_generic_node (buffer, VDEF_OP (vdefs, i), spc + 2, flags, false);
+      dump_generic_node (buffer, V_MAY_DEF_RESULT (v_may_defs, i), spc + 2, flags, false);
+      pp_string (buffer, " = V_MAY_DEF <");
+      dump_generic_node (buffer, V_MAY_DEF_OP (v_may_defs, i), spc + 2, flags, false);
+      pp_string (buffer, ">;");
+      newline_and_indent (buffer, spc);
+    }
+
+  for (i = 0; i < NUM_V_MUST_DEFS (v_must_defs); i++)
+    {
+      tree v_must_def = V_MUST_DEF_OP (v_must_defs, i);
+      pp_string (buffer, "#   V_MUST_DEF <");
+      dump_generic_node (buffer, v_must_def, spc + 2, flags, false);
       pp_string (buffer, ">;");
       newline_and_indent (buffer, spc);
     }
Index: tree-sra.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-sra.c,v
retrieving revision 2.3
diff -c -p -u -p -r2.3 tree-sra.c
--- tree-sra.c	14 May 2004 15:27:36 -0000	2.3
+++ tree-sra.c	27 May 2004 18:32:54 -0000
@@ -112,22 +112,42 @@ sra_elt_eq (const void *x, const void *y
   return true;
 }
 
-/* Mark all the variables in VDEF operands for STMT for renaming.
+/* Mark all the variables in V_MAY_DEF operands for STMT for renaming.
    This becomes necessary when we modify all of a non-scalar.  */
 
 static void
-mark_all_vdefs (tree stmt)
+mark_all_v_may_defs (tree stmt)
 {
-  vdef_optype vdefs;
+  v_may_def_optype v_may_defs;
   size_t i, n;
 
   get_stmt_operands (stmt);
-  vdefs = VDEF_OPS (stmt_ann (stmt));
-  n = NUM_VDEFS (vdefs);
+  v_may_defs = V_MAY_DEF_OPS (stmt_ann (stmt));
+  n = NUM_V_MAY_DEFS (v_may_defs);
 
   for (i = 0; i < n; i++)
     {
-      tree sym = VDEF_RESULT (vdefs, i);
+      tree sym = V_MAY_DEF_RESULT (v_may_defs, i);
+      bitmap_set_bit (vars_to_rename, var_ann (sym)->uid);
+    }
+}
+
+/* Mark all the variables in V_MUST_DEF operands for STMT for renaming.
+   This becomes necessary when we modify all of a non-scalar.  */
+
+static void
+mark_all_v_must_defs (tree stmt)
+{
+  v_must_def_optype v_must_defs;
+  size_t i, n;
+
+  get_stmt_operands (stmt);
+  v_must_defs = V_MUST_DEF_OPS (stmt_ann (stmt));
+  n = NUM_V_MUST_DEFS (v_must_defs);
+
+  for (i = 0; i < n; i++)
+    {
+      tree sym = V_MUST_DEF_OP (v_must_defs, i);
       bitmap_set_bit (vars_to_rename, var_ann (sym)->uid);
     }
 }
@@ -685,7 +705,8 @@ create_scalar_copies (tree lhs, tree rhs
 
       /* Mark all the variables in VDEF operands for renaming, because
 	 the VA_ARG_EXPR will now be in a different statement.  */
-      mark_all_vdefs (stmt);
+      mark_all_v_may_defs (stmt);
+      mark_all_v_must_defs (stmt);
 
       /* Set RHS to be the new temporary TMP.  */
       rhs = tmp;
@@ -784,7 +805,8 @@ create_scalar_copies (tree lhs, tree rhs
 	  /* Otherwise, mark all the symbols in the VDEFs for the last
 	     scalarized statement just created.  Since all the statements
 	     introduce the same VDEFs, we only need to check the last one.  */
-	  mark_all_vdefs (tsi_stmt (tsi));
+	  mark_all_v_may_defs (tsi_stmt (tsi));
+	  mark_all_v_must_defs (tsi_stmt (tsi));
 	}
       else
 	abort ();
@@ -830,8 +852,9 @@ scalarize_structures (void)
 
 	/* If the statement has no virtual operands, then it doesn't make
 	   structure references that we care about.  */
-	if (NUM_VDEFS (VDEF_OPS (ann)) == 0
-	    && NUM_VUSES (VUSE_OPS (ann)) == 0)
+	if (NUM_V_MAY_DEFS (V_MAY_DEF_OPS (ann)) == 0
+	    && NUM_VUSES (VUSE_OPS (ann)) == 0
+	    && NUM_V_MUST_DEFS (V_MUST_DEF_OPS (ann)) == 0)
 	  continue;
 
 	/* Structure references may only appear in certain statements.  */
@@ -899,17 +922,17 @@ scalarize_modify_expr (block_stmt_iterat
   if (is_sra_candidate_ref (lhs, false))
     {
       tree sym;
-      vdef_optype vdefs;
+      v_may_def_optype v_may_defs;
 
       scalarize_component_ref (stmt, &TREE_OPERAND (stmt, 0));
 
       /* Mark the LHS to be renamed, as we have just removed the previous
-	 VDEF for AGGREGATE.  The statement should have exactly one VDEF
+	 V_MAY_DEF for AGGREGATE.  The statement should have exactly one V_MAY_DEF
 	 for variable AGGREGATE.  */
-      vdefs = STMT_VDEF_OPS (stmt);
-      if (NUM_VDEFS (vdefs) != 1)
+      v_may_defs = STMT_V_MAY_DEF_OPS (stmt);
+      if (NUM_V_MAY_DEFS (v_may_defs) != 1)
 	abort ();
-      sym = SSA_NAME_VAR (VDEF_RESULT (vdefs, 0));
+      sym = SSA_NAME_VAR (V_MAY_DEF_RESULT (v_may_defs, 0));
       bitmap_set_bit (vars_to_rename, var_ann (sym)->uid);
     }
 
Index: tree-ssa-alias.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-ssa-alias.c,v
retrieving revision 2.4
diff -c -p -u -p -r2.4 tree-ssa-alias.c
--- tree-ssa-alias.c	15 May 2004 23:07:52 -0000	2.4
+++ tree-ssa-alias.c	27 May 2004 18:32:54 -0000
@@ -173,7 +173,7 @@ bool aliases_computed_p;
    this variable is used to represent the clobbering effects of function
    calls.  In these cases, all the call clobbered variables in the program
    are forced to alias this variable.  This reduces compile times by not
-   having to keep track of too many VDEF expressions at call sites.  */
+   having to keep track of too many V_MAY_DEF expressions at call sites.  */
 tree global_var;
 
 
@@ -263,11 +263,11 @@ tree global_var;
 		p_6 = &b;
 	      # p_1 = PHI <p_4(1), p_6(2)>;
 
-	      # a_7 = VDEF <a_3>;
-	      # b_8 = VDEF <b_5>;
+	      # a_7 = V_MAY_DEF <a_3>;
+	      # b_8 = V_MAY_DEF <b_5>;
 	      *p_1 = 3;
 
-	      # a_9 = VDEF <a_7>
+	      # a_9 = V_MAY_DEF <a_7>
 	      # VUSE <b_8>
 	      a_9 = b_8 + 2;
 
@@ -535,7 +535,8 @@ compute_points_to_and_addr_escape (struc
 	{
 	  use_optype uses;
 	  def_optype defs;
-	  vdef_optype vdefs;
+	  v_may_def_optype v_may_defs;
+	  v_must_def_optype v_must_defs;
 	  stmt_ann_t ann;
 	  bitmap addr_taken;
 	  tree stmt = bsi_stmt (si);
@@ -656,11 +657,21 @@ compute_points_to_and_addr_escape (struc
 		(VARRAY_UINT (ai->num_references, ann->uid))++;
 	    }
 
-	  /* Mark variables in VDEF operands as being written to.  */
-	  vdefs = VDEF_OPS (ann);
-	  for (i = 0; i < NUM_VDEFS (vdefs); i++)
+	  /* Mark variables in V_MAY_DEF operands as being written to.  */
+	  v_may_defs = V_MAY_DEF_OPS (ann);
+	  for (i = 0; i < NUM_V_MAY_DEFS (v_may_defs); i++)
 	    {
-	      tree op = VDEF_OP (vdefs, i);
+	      tree op = V_MAY_DEF_OP (v_may_defs, i);
+	      tree var = SSA_NAME_VAR (op);
+	      var_ann_t ann = var_ann (var);
+	      bitmap_set_bit (ai->written_vars, ann->uid);
+	    }
+	    
+	  /* Mark variables in V_MUST_DEF operands as being written to.  */
+	  v_must_defs = V_MUST_DEF_OPS (ann);
+	  for (i = 0; i < NUM_V_MUST_DEFS (v_must_defs); i++)
+	    {
+	      tree op = V_MUST_DEF_OP (v_must_defs, i);
 	      tree var = SSA_NAME_VAR (op);
 	      var_ann_t ann = var_ann (var);
 	      bitmap_set_bit (ai->written_vars, ann->uid);
@@ -1036,7 +1047,7 @@ group_aliases (struct alias_info *ai)
 
      	p_5 = &a;
 	...
-	# a_9 = VDEF <a_8>
+	# a_9 = V_MAY_DEF <a_8>
 	p_5->field = 0
 	... Several modifications to TMT.20 ... 
 	# VUSE <a_9>
@@ -1270,7 +1281,7 @@ setup_pointers_and_addressables (struct 
 
 
 /* Determine whether to use .GLOBAL_VAR to model call clobbering semantics.  At
-   every call site, we need to emit VDEF expressions to represent the
+   every call site, we need to emit V_MAY_DEF expressions to represent the
    clobbering effects of the call for variables whose address escapes the
    current function.
 
@@ -1279,9 +1290,9 @@ setup_pointers_and_addressables (struct 
    (.GLOBAL_VAR).  This works well, but it ties the optimizer hands because
    references to any call clobbered variable is a reference to .GLOBAL_VAR.
 
-   The second approach is to emit a clobbering VDEF for every call-clobbered
+   The second approach is to emit a clobbering V_MAY_DEF for every call-clobbered
    variable at call sites.  This is the preferred way in terms of optimization
-   opportunities but it may create too many VDEF operands if there are many
+   opportunities but it may create too many V_MAY_DEF operands if there are many
    call clobbered variables and function calls in the function.
 
    To decide whether or not to use .GLOBAL_VAR we multiply the number of
Index: tree-ssa.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-ssa.c,v
retrieving revision 2.3
diff -c -p -u -p -r2.3 tree-ssa.c
--- tree-ssa.c	14 May 2004 02:29:23 -0000	2.3
+++ tree-ssa.c	27 May 2004 18:32:54 -0000
@@ -314,17 +314,18 @@ verify_ssa (void)
 	  tree stmt;
 	  stmt_ann_t ann;
 	  unsigned int j;
-	  vdef_optype vdefs;
+	  v_may_def_optype v_may_defs;
+	  v_must_def_optype v_must_defs;
 	  def_optype defs;
 
 	  stmt = bsi_stmt (bsi);
 	  ann = stmt_ann (stmt);
 	  get_stmt_operands (stmt);
 
-	  vdefs = VDEF_OPS (ann);
-	  for (j = 0; j < NUM_VDEFS (vdefs); j++)
+	  v_may_defs = V_MAY_DEF_OPS (ann);
+	  for (j = 0; j < NUM_V_MAY_DEFS (v_may_defs); j++)
 	    {
-	      tree op = VDEF_RESULT (vdefs, j);
+	      tree op = V_MAY_DEF_RESULT (v_may_defs, j);
 	      if (is_gimple_reg (op))
 		{
 		  error ("Found a virtual definition for a GIMPLE register");
@@ -334,6 +335,20 @@ verify_ssa (void)
 		}
 	      err |= verify_def (bb, definition_block, op, stmt);
 	    }
+          
+	  v_must_defs = STMT_V_MUST_DEF_OPS (stmt);
+	  for (j = 0; j < NUM_V_MUST_DEFS (v_must_defs); j++)
+	    {
+	      tree op = V_MUST_DEF_OP (v_must_defs, j);
+	      if (is_gimple_reg (op))
+		{
+		  error ("Found a virtual must-def for a GIMPLE register");
+		  debug_generic_stmt (op);
+		  debug_generic_stmt (stmt);
+		  err = true;
+		}
+	      err |= verify_def (bb, definition_block, op, stmt);
+	    }
 
 	  defs = DEF_OPS (ann);
 	  for (j = 0; j < NUM_DEFS (defs); j++)
@@ -377,14 +392,14 @@ verify_ssa (void)
 
       /* Now verify all the uses and vuses in every statement of the block. 
 
-	 Remember, the RHS of a VDEF is a use as well.  */
+	 Remember, the RHS of a V_MAY_DEF is a use as well.  */
       for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
 	{
 	  tree stmt = bsi_stmt (bsi);
 	  stmt_ann_t ann = stmt_ann (stmt);
 	  unsigned int j;
 	  vuse_optype vuses;
-	  vdef_optype vdefs;
+	  v_may_def_optype v_may_defs;
 	  use_optype uses;
 
 	  vuses = VUSE_OPS (ann);
@@ -403,10 +418,10 @@ verify_ssa (void)
 				 op, stmt, false);
 	    }
 
-	  vdefs = VDEF_OPS (ann);
-	  for (j = 0; j < NUM_VDEFS (vdefs); j++)
+	  v_may_defs = V_MAY_DEF_OPS (ann);
+	  for (j = 0; j < NUM_V_MAY_DEFS (v_may_defs); j++)
 	    {
-	      tree op = VDEF_OP (vdefs, j);
+	      tree op = V_MAY_DEF_OP (v_may_defs, j);
 
 	      if (is_gimple_reg (op))
 		{
@@ -695,7 +710,7 @@ replace_immediate_uses (tree var, tree r
 {
   use_optype uses;
   vuse_optype vuses;
-  vdef_optype vdefs;
+  v_may_def_optype v_may_defs;
   int i, j, n;
   dataflow_t df;
   tree stmt;
@@ -738,10 +753,10 @@ replace_immediate_uses (tree var, tree r
 	    if (VUSE_OP (vuses, j) == var)
 	      propagate_value (VUSE_OP_PTR (vuses, j), repl);
 
-	  vdefs = VDEF_OPS (ann);
-	  for (j = 0; j < (int) NUM_VDEFS (vdefs); j++)
-	    if (VDEF_OP (vdefs, j) == var)
-	      propagate_value (VDEF_OP_PTR (vdefs, j), repl);
+	  v_may_defs = V_MAY_DEF_OPS (ann);
+	  for (j = 0; j < (int) NUM_V_MAY_DEFS (v_may_defs); j++)
+	    if (V_MAY_DEF_OP (v_may_defs, j) == var)
+	      propagate_value (V_MAY_DEF_OP_PTR (v_may_defs, j), repl);
 	}
 
       modify_stmt (stmt);
Index: tree-ssa-ccp.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-ssa-ccp.c,v
retrieving revision 2.2
diff -c -p -u -p -r2.2 tree-ssa-ccp.c
--- tree-ssa-ccp.c	14 May 2004 02:29:23 -0000	2.2
+++ tree-ssa-ccp.c	27 May 2004 18:32:54 -0000
@@ -575,7 +575,8 @@ visit_stmt (tree stmt)
   size_t i;
   stmt_ann_t ann;
   def_optype defs;
-  vdef_optype vdefs;
+  v_may_def_optype v_may_defs;
+  v_must_def_optype v_must_defs;
 
   /* If the statement has already been deemed to be VARYING, don't simulate
      it again.  */
@@ -634,10 +635,15 @@ visit_stmt (tree stmt)
 	add_outgoing_control_edges (bb_for_stmt (stmt));
     }
 
-  /* Mark all VDEF operands VARYING.  */
-  vdefs = VDEF_OPS (ann);
-  for (i = 0; i < NUM_VDEFS (vdefs); i++)
-    def_to_varying (VDEF_RESULT (vdefs, i));
+  /* Mark all V_MAY_DEF operands VARYING.  */
+  v_may_defs = V_MAY_DEF_OPS (ann);
+  for (i = 0; i < NUM_V_MAY_DEFS (v_may_defs); i++)
+    def_to_varying (V_MAY_DEF_RESULT (v_may_defs, i));
+    
+  /* Mark all V_MUST_DEF operands VARYING.  */
+  v_must_defs = V_MUST_DEF_OPS (ann);
+  for (i = 0; i < NUM_V_MUST_DEFS (v_must_defs); i++)
+    def_to_varying (V_MUST_DEF_OP (v_must_defs, i));
 }
 
 
@@ -1093,7 +1099,8 @@ initialize (void)
       tree stmt;
       stmt_ann_t ann;
       def_optype defs;
-      vdef_optype vdefs;
+      v_may_def_optype v_may_defs;
+      v_must_def_optype v_must_defs;
       size_t x;
       int vary;
 
@@ -1113,14 +1120,23 @@ initialize (void)
 	    }
 	  DONT_SIMULATE_AGAIN (stmt) = vary;
 
-	  /* Mark all VDEF operands VARYING.  */
-	  vdefs = VDEF_OPS (ann);
-	  for (x = 0; x < NUM_VDEFS (vdefs); x++)
+	  /* Mark all V_MAY_DEF operands VARYING.  */
+	  v_may_defs = V_MAY_DEF_OPS (ann);
+	  for (x = 0; x < NUM_V_MAY_DEFS (v_may_defs); x++)
 	    {
-	      tree res = VDEF_RESULT (vdefs, x);
+	      tree res = V_MAY_DEF_RESULT (v_may_defs, x);
 	      get_value (res)->lattice_val = VARYING;
 	      SET_BIT (virtual_var, SSA_NAME_VERSION (res));
 	    }
+	    
+	  /* Mark all V_MUST_DEF operands VARYING.  */
+	  v_must_defs = V_MUST_DEF_OPS (ann);
+	  for (x = 0; x < NUM_V_MUST_DEFS (v_must_defs); x++)
+	    {
+	      tree v_must_def = V_MUST_DEF_OP (v_must_defs, x);
+	      get_value (v_must_def)->lattice_val = VARYING;
+	      SET_BIT (virtual_var, SSA_NAME_VERSION (v_must_def));
+	    }
 	}
 
       for (e = bb->succ; e; e = e->succ_next)
@@ -2024,7 +2040,8 @@ set_rhs (tree *stmt_p, tree expr)
       if (TREE_SIDE_EFFECTS (expr))
 	{
 	  def_optype defs;
-	  vdef_optype vdefs;
+	  v_may_def_optype v_may_defs;
+	  v_must_def_optype v_must_defs;
 	  size_t i;
 
 	  /* Fix all the SSA_NAMEs created by *STMT_P to point to its new
@@ -2037,10 +2054,18 @@ set_rhs (tree *stmt_p, tree expr)
 		SSA_NAME_DEF_STMT (var) = *stmt_p;
 	    }
 
-	  vdefs = VDEF_OPS (ann);
-	  for (i = 0; i < NUM_VDEFS (vdefs); i++)
+	  v_may_defs = V_MAY_DEF_OPS (ann);
+	  for (i = 0; i < NUM_V_MAY_DEFS (v_may_defs); i++)
+	    {
+	      tree var = V_MAY_DEF_RESULT (v_may_defs, i);
+	      if (TREE_CODE (var) == SSA_NAME)
+		SSA_NAME_DEF_STMT (var) = *stmt_p;
+	    }
+	    
+	  v_must_defs = V_MUST_DEF_OPS (ann);
+	  for (i = 0; i < NUM_V_MUST_DEFS (v_must_defs); i++)
 	    {
-	      tree var = VDEF_RESULT (vdefs, i);
+	      tree var = V_MUST_DEF_OP (v_must_defs, i);
 	      if (TREE_CODE (var) == SSA_NAME)
 		SSA_NAME_DEF_STMT (var) = *stmt_p;
 	    }
Index: tree-ssa-copy.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-ssa-copy.c,v
retrieving revision 2.2
diff -c -p -u -p -r2.2 tree-ssa-copy.c
--- tree-ssa-copy.c	18 May 2004 02:55:41 -0000	2.2
+++ tree-ssa-copy.c	27 May 2004 18:32:54 -0000
@@ -225,16 +225,16 @@ cprop_operand (stmt_ann_t ann, tree *op_
    known value for that SSA_NAME (or NULL if no value is known).  
 
    Propagate values from CONST_AND_COPIES into the uses, vuses and
-   vdef_ops of STMT.  */
+   v_may_def_ops of STMT.  */
 
 bool
 cprop_into_stmt (tree stmt, varray_type const_and_copies)
 {
   bool may_have_exposed_new_symbols = false;
   stmt_ann_t ann = stmt_ann (stmt);
-  size_t i, num_uses, num_vuses, num_vdefs;
+  size_t i, num_uses, num_vuses, num_v_may_defs;
   vuse_optype vuses;
-  vdef_optype vdefs;
+  v_may_def_optype v_may_defs;
   use_optype uses;
 
   uses = USE_OPS (ann);
@@ -257,11 +257,11 @@ cprop_into_stmt (tree stmt, varray_type 
 	  |= cprop_operand (ann, op_p, const_and_copies);
     }
 
-  vdefs = VDEF_OPS (ann);
-  num_vdefs = NUM_VDEFS (vdefs);
-  for (i = 0; i < num_vdefs; i++)
+  v_may_defs = V_MAY_DEF_OPS (ann);
+  num_v_may_defs = NUM_V_MAY_DEFS (v_may_defs);
+  for (i = 0; i < num_v_may_defs; i++)
     {
-      tree *op_p = VDEF_OP_PTR (vdefs, i);
+      tree *op_p = V_MAY_DEF_OP_PTR (v_may_defs, i);
       if (TREE_CODE (*op_p) == SSA_NAME)
 	may_have_exposed_new_symbols
 	  |= cprop_operand (ann, op_p, const_and_copies);
Index: tree-ssa-dce.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-ssa-dce.c,v
retrieving revision 2.3
diff -c -p -u -p -r2.3 tree-ssa-dce.c
--- tree-ssa-dce.c	14 May 2004 02:29:23 -0000	2.3
+++ tree-ssa-dce.c	27 May 2004 18:32:54 -0000
@@ -286,7 +286,8 @@ static void
 mark_stmt_if_obviously_necessary (tree stmt, bool aggressive)
 {
   def_optype defs;
-  vdef_optype vdefs;
+  v_may_def_optype v_may_defs;
+  v_must_def_optype v_must_defs;
   stmt_ann_t ann;
   size_t i;
 
@@ -387,11 +388,22 @@ mark_stmt_if_obviously_necessary (tree s
         }
     }
 
-  vdefs = VDEF_OPS (ann);
-  for (i = 0; i < NUM_VDEFS (vdefs); i++)
+  v_may_defs = V_MAY_DEF_OPS (ann);
+  for (i = 0; i < NUM_V_MAY_DEFS (v_may_defs); i++)
     {
-      tree vdef = VDEF_RESULT (vdefs, i);
-      if (need_to_preserve_store (vdef))
+      tree v_may_def = V_MAY_DEF_RESULT (v_may_defs, i);
+      if (need_to_preserve_store (v_may_def))
+	{
+	  mark_stmt_necessary (stmt, true);
+	  return;
+        }
+    }
+    
+  v_must_defs = V_MUST_DEF_OPS (ann);
+  for (i = 0; i < NUM_V_MUST_DEFS (v_must_defs); i++)
+    {
+      tree v_must_def = V_MUST_DEF_OP (v_must_defs, i);
+      if (need_to_preserve_store (v_must_def))
 	{
 	  mark_stmt_necessary (stmt, true);
 	  return;
@@ -558,10 +570,10 @@ propagate_necessity (struct edge_list *e
       else
 	{
 	  /* Propagate through the operands.  Examine all the USE, VUSE and
-	     VDEF operands in this statement.  Mark all the statements which
+	     V_MAY_DEF operands in this statement.  Mark all the statements which
 	     feed this statement's uses as necessary.  */
 	  vuse_optype vuses;
-	  vdef_optype vdefs;
+	  v_may_def_optype v_may_defs;
 	  use_optype uses;
 	  stmt_ann_t ann;
 	  size_t k;
@@ -577,12 +589,12 @@ propagate_necessity (struct edge_list *e
 	  for (k = 0; k < NUM_VUSES (vuses); k++)
 	    mark_operand_necessary (VUSE_OP (vuses, k));
 
-	  /* The operands of VDEF expressions are also needed as they
+	  /* The operands of V_MAY_DEF expressions are also needed as they
 	     represent potential definitions that may reach this
-	     statement (VDEF operands allow us to follow def-def links).  */
-	  vdefs = VDEF_OPS (ann);
-	  for (k = 0; k < NUM_VDEFS (vdefs); k++)
-	    mark_operand_necessary (VDEF_OP (vdefs, k));
+	     statement (V_MAY_DEF operands allow us to follow def-def links).  */
+	  v_may_defs = V_MAY_DEF_OPS (ann);
+	  for (k = 0; k < NUM_V_MAY_DEFS (v_may_defs); k++)
+	    mark_operand_necessary (V_MAY_DEF_OP (v_may_defs, k));
 	}
     }
 }
Index: tree-ssa-dom.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-ssa-dom.c,v
retrieving revision 2.5
diff -c -p -u -p -r2.5 tree-ssa-dom.c
--- tree-ssa-dom.c	18 May 2004 02:53:55 -0000	2.5
+++ tree-ssa-dom.c	27 May 2004 18:32:54 -0000
@@ -347,7 +347,8 @@ redirect_edges_and_update_ssa_graph (var
 	{
 	  unsigned int j;
 	  def_optype defs;
-	  vdef_optype vdefs;
+	  v_may_def_optype v_may_defs;
+	  v_must_def_optype v_must_defs;
 	  tree stmt = bsi_stmt (bsi);
 	  stmt_ann_t ann = stmt_ann (stmt);
 
@@ -363,11 +364,18 @@ redirect_edges_and_update_ssa_graph (var
 	      bitmap_set_bit (vars_to_rename, var_ann (op)->uid);
 	    }
 
-	  vdefs = VDEF_OPS (ann);
-	  for (j = 0; j < NUM_VDEFS (vdefs); j++)
+	  v_may_defs = STMT_V_MAY_DEF_OPS (stmt);
+	  for (j = 0; j < NUM_V_MAY_DEFS (v_may_defs); j++)
 	    {
-	      tree op = VDEF_RESULT (vdefs, j);
-	      bitmap_set_bit (virtuals_to_rename, var_ann (op)->uid);
+	      tree op = V_MAY_DEF_RESULT (v_may_defs, j);
+	      bitmap_set_bit (vars_to_rename, var_ann (op)->uid);
+	    }
+	    
+	  v_must_defs = STMT_V_MUST_DEF_OPS (stmt);
+	  for (j = 0; j < NUM_V_MUST_DEFS (v_must_defs); j++)
+	    {
+	      tree op = V_MUST_DEF_OP (v_must_defs, j);
+	      bitmap_set_bit (vars_to_rename, var_ann (op)->uid);
 	    }
 	}
 
@@ -2285,7 +2293,7 @@ static bool
 eliminate_redundant_computations (struct dom_walk_data *walk_data,
 				  tree stmt, stmt_ann_t ann)
 {
-  vdef_optype vdefs = VDEF_OPS (ann);
+  v_may_def_optype v_may_defs = V_MAY_DEF_OPS (ann);
   tree *expr_p, def = NULL_TREE;
   bool insert = true;
   tree cached_lhs;
@@ -2302,7 +2310,7 @@ eliminate_redundant_computations (struct
       || ! def
       || TREE_CODE (def) != SSA_NAME
       || SSA_NAME_OCCURS_IN_ABNORMAL_PHI (def)
-      || NUM_VDEFS (vdefs) != 0)
+      || NUM_V_MAY_DEFS (v_may_defs) != 0)
     insert = false;
 
   /* Check if the expression has been computed before.  */
@@ -2507,7 +2515,8 @@ record_equivalences_from_stmt (tree stmt
 
       if (rhs)
 	{
-	  vdef_optype vdefs = VDEF_OPS (ann);
+	  v_may_def_optype v_may_defs = V_MAY_DEF_OPS (ann);
+	  v_must_def_optype v_must_defs = V_MUST_DEF_OPS (ann);
 
 	  /* Build a new statement with the RHS and LHS exchanged.  */
 	  new = build (MODIFY_EXPR, TREE_TYPE (stmt), rhs, lhs);
@@ -2519,14 +2528,21 @@ record_equivalences_from_stmt (tree stmt
 	  /* Clear out the virtual operands on the new statement, we are
 	     going to set them explicitly below.  */
 	  remove_vuses (new);
-	  remove_vdefs (new);
+	  remove_v_may_defs (new);
+	  remove_v_must_defs (new);
 
 	  start_ssa_stmt_operands (new);
 	  /* For each VDEF on the original statement, we want to create a
-	     VUSE of the VDEF result on the new statement.  */
-	  for (j = 0; j < NUM_VDEFS (vdefs); j++)
+	     VUSE of the V_MAY_DEF result or V_MUST_DEF op on the new statement.  */
+	  for (j = 0; j < NUM_V_MAY_DEFS (v_may_defs); j++)
 	    {
-	      tree op = VDEF_RESULT (vdefs, j);
+	      tree op = V_MAY_DEF_RESULT (v_may_defs, j);
+	      add_vuse (op, new);
+	    }
+	    
+	  for (j = 0; j < NUM_V_MUST_DEFS (v_must_defs); j++)
+	    {
+	      tree op = V_MUST_DEF_OP (v_must_defs, j);
 	      add_vuse (op, new);
 	    }
 
@@ -2561,7 +2577,6 @@ optimize_stmt (struct dom_walk_data *wal
 {
   stmt_ann_t ann;
   tree stmt;
-  vdef_optype vdefs;
   bool may_optimize_p;
   bool may_have_exposed_new_symbols = false;
   struct dom_walk_block_data *bd
@@ -2571,7 +2586,6 @@ optimize_stmt (struct dom_walk_data *wal
 
   get_stmt_operands (stmt);
   ann = stmt_ann (stmt);
-  vdefs = VDEF_OPS (ann);
   opt_stats.num_stmts++;
   may_have_exposed_new_symbols = false;
 
@@ -2581,7 +2595,7 @@ optimize_stmt (struct dom_walk_data *wal
       print_generic_stmt (dump_file, stmt, TDF_SLIM);
     }
 
-  /* Const/copy propagate into USES, VUSES and the RHS of VDEFs.  */
+  /* Const/copy propagate into USES, VUSES and the RHS of V_MAY_DEFs.  */
   may_have_exposed_new_symbols = cprop_into_stmt (stmt, const_and_copies);
 
   /* If the statement has been modified with constant replacements,
@@ -3167,7 +3181,8 @@ static void
 register_definitions_for_stmt (stmt_ann_t ann, varray_type *block_defs_p)
 {
   def_optype defs;
-  vdef_optype vdefs;
+  v_may_def_optype v_may_defs;
+  v_must_def_optype v_must_defs;
   unsigned int i;
 
   defs = DEF_OPS (ann);
@@ -3181,12 +3196,21 @@ register_definitions_for_stmt (stmt_ann_
     }
 
   /* Register new virtual definitions made by the statement.  */
-  vdefs = VDEF_OPS (ann);
-  for (i = 0; i < NUM_VDEFS (vdefs); i++)
+  v_may_defs = V_MAY_DEF_OPS (ann);
+  for (i = 0; i < NUM_V_MAY_DEFS (v_may_defs); i++)
+    {
+      /* FIXME: We shouldn't be registering new defs if the variable
+	 doesn't need to be renamed.  */
+      register_new_def (V_MAY_DEF_RESULT (v_may_defs, i), block_defs_p);
+    }
+    
+  /* Register new virtual mustdefs made by the statement.  */
+  v_must_defs = V_MUST_DEF_OPS (ann);
+  for (i = 0; i < NUM_V_MUST_DEFS (v_must_defs); i++)
     {
       /* FIXME: We shouldn't be registering new defs if the variable
 	 doesn't need to be renamed.  */
-      register_new_def (VDEF_RESULT (vdefs, i), block_defs_p);
+      register_new_def (V_MUST_DEF_OP (v_must_defs, i), block_defs_p);
     }
 }
 
Index: tree-ssa-dse.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-ssa-dse.c,v
retrieving revision 2.1
diff -c -p -u -p -r2.1 tree-ssa-dse.c
--- tree-ssa-dse.c	13 May 2004 06:39:49 -0000	2.1
+++ tree-ssa-dse.c	27 May 2004 18:32:55 -0000
@@ -95,7 +95,7 @@ static void dse_optimize_stmt (struct do
 static void dse_record_phis (struct dom_walk_data *, basic_block);
 static void dse_finalize_block (struct dom_walk_data *, basic_block);
 static void fix_phi_uses (tree, tree);
-static void fix_stmt_vdefs (tree, tree);
+static void fix_stmt_v_may_defs (tree, tree);
 static void record_voperand_set (bitmap, bitmap *, unsigned int);
 
 /* Function indicating whether we ought to include information for 'var'
@@ -109,70 +109,70 @@ need_imm_uses_for (tree var)
 }
 
 
-/* Replace uses in PHI which match VDEF_RESULTs in STMT with the 
-   corresponding VDEF_OP in STMT.  */
+/* Replace uses in PHI which match V_MAY_DEF_RESULTs in STMT with the 
+   corresponding V_MAY_DEF_OP in STMT.  */
 
 static void
 fix_phi_uses (tree phi, tree stmt)
 {
   stmt_ann_t ann = stmt_ann (stmt);
-  vdef_optype vdefs;
+  v_may_def_optype v_may_defs;
   unsigned int i;
   int j;
 
   get_stmt_operands (stmt);
-  vdefs = VDEF_OPS (ann);
+  v_may_defs = V_MAY_DEF_OPS (ann);
 
-  /* Walk each VDEF in STMT.  */
-  for (i = 0; i < NUM_VDEFS (vdefs); i++)
+  /* Walk each V_MAY_DEF in STMT.  */
+  for (i = 0; i < NUM_V_MAY_DEFS (v_may_defs); i++)
     {
-      tree vdef = VDEF_RESULT (vdefs, i);
+      tree v_may_def = V_MAY_DEF_RESULT (v_may_defs, i);
 
-      /* Find any uses in the PHI which match VDEF and replace
-	 them with the appropriate VDEF_OP.  */
+      /* Find any uses in the PHI which match V_MAY_DEF and replace
+	 them with the appropriate V_MAY_DEF_OP.  */
       for (j = 0; j < PHI_NUM_ARGS (phi); j++)
-	if (vdef == PHI_ARG_DEF (phi, j))
-	  PHI_ARG_DEF (phi, j) = VDEF_OP (vdefs, i);
+	if (v_may_def == PHI_ARG_DEF (phi, j))
+	  PHI_ARG_DEF (phi, j) = V_MAY_DEF_OP (v_may_defs, i);
     }
 }
 
-/* Replace the VDEF_OPs in STMT1 which match VDEF_RESULTs in STMT2 with
-   the appropriate VDEF_OPs from STMT2.  */
+/* Replace the V_MAY_DEF_OPs in STMT1 which match V_MAY_DEF_RESULTs in STMT2 with
+   the appropriate V_MAY_DEF_OPs from STMT2.  */
 
 static void
-fix_stmt_vdefs (tree stmt1, tree stmt2)
+fix_stmt_v_may_defs (tree stmt1, tree stmt2)
 {
   stmt_ann_t ann1 = stmt_ann (stmt1);
   stmt_ann_t ann2 = stmt_ann (stmt2);
-  vdef_optype vdefs1;
-  vdef_optype vdefs2;
+  v_may_def_optype v_may_defs1;
+  v_may_def_optype v_may_defs2;
   unsigned int i, j;
 
   get_stmt_operands (stmt1);
   get_stmt_operands (stmt2);
-  vdefs1 = VDEF_OPS (ann1);
-  vdefs2 = VDEF_OPS (ann2);
+  v_may_defs1 = V_MAY_DEF_OPS (ann1);
+  v_may_defs2 = V_MAY_DEF_OPS (ann2);
 
-  /* Walk each VDEF_OP in stmt1.  */
-  for (i = 0; i < NUM_VDEFS (vdefs1); i++)
+  /* Walk each V_MAY_DEF_OP in stmt1.  */
+  for (i = 0; i < NUM_V_MAY_DEFS (v_may_defs1); i++)
     {
-      tree vdef1 = VDEF_OP (vdefs1, i);
+      tree v_may_def1 = V_MAY_DEF_OP (v_may_defs1, i);
 
-      /* Find the appropriate VDEF_RESULT in STMT2.  */
-      for (j = 0; j < NUM_VDEFS (vdefs2); j++)
+      /* Find the appropriate V_MAY_DEF_RESULT in STMT2.  */
+      for (j = 0; j < NUM_V_MAY_DEFS (v_may_defs2); j++)
 	{
-	  if (vdef1 == VDEF_RESULT (vdefs2, j))
+	  if (v_may_def1 == V_MAY_DEF_RESULT (v_may_defs2, j))
 	    {
 	      /* Update.  */
-	      *VDEF_OP_PTR (vdefs1, i) = VDEF_OP (vdefs2, j);
+	      *V_MAY_DEF_OP_PTR (v_may_defs1, i) = V_MAY_DEF_OP (v_may_defs2, j);
 	      break;
 	    }
 	}
 
 #ifdef ENABLE_CHECKING
-      /* If we did not find a corresponding VDEF_RESULT, then something
+      /* If we did not find a corresponding V_MAY_DEF_RESULT, then something
 	 has gone terribly wrong.  */
-      if (j == NUM_VDEFS (vdefs2))
+      if (j == NUM_V_MAY_DEFS (v_may_defs2))
 	abort ();
 #endif
 
@@ -234,14 +234,14 @@ dse_optimize_stmt (struct dom_walk_data 
   struct dse_global_data *dse_gd = walk_data->global_data;
   tree stmt = bsi_stmt (bsi);
   stmt_ann_t ann = stmt_ann (stmt);
-  vdef_optype vdefs;
+  v_may_def_optype v_may_defs;
 
   get_stmt_operands (stmt);
-  vdefs = VDEF_OPS (ann);
+  v_may_defs = V_MAY_DEF_OPS (ann);
 
   /* If this statement has no virtual uses, then there is nothing
      to do.  */
-  if (NUM_VDEFS (vdefs) == 0)
+  if (NUM_V_MAY_DEFS (v_may_defs) == 0)
     return;
 
   /* We know we have virtual definitions.  If this is a MODIFY_EXPR, then
@@ -269,7 +269,7 @@ dse_optimize_stmt (struct dom_walk_data 
 	 represents the only use of this store.
 
 	 Note this does not handle the case where the store has
-	 multiple VDEFs which all reach a set of PHI nodes in the
+	 multiple V_MAY_DEFs which all reach a set of PHI nodes in the
 	 same block.  */
       while (num_uses == 1
 	     && TREE_CODE (use) == PHI_NODE
@@ -300,7 +300,7 @@ dse_optimize_stmt (struct dom_walk_data 
 	  if (skipped_phi)
 	    fix_phi_uses (skipped_phi, stmt);
 	  else
-	    fix_stmt_vdefs (use, stmt);
+	    fix_stmt_v_may_defs (use, stmt);
 
 	  if (dump_file && (dump_flags & TDF_DETAILS))
             {
Index: tree-ssa-live.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-ssa-live.c,v
retrieving revision 2.4
diff -c -p -u -p -r2.4 tree-ssa-live.c
--- tree-ssa-live.c	14 May 2004 05:08:55 -0000	2.4
+++ tree-ssa-live.c	27 May 2004 18:32:55 -0000
@@ -298,7 +298,8 @@ create_ssa_var_map (int flags)
   tree stmt;
   stmt_ann_t ann;
   vuse_optype vuses;
-  vdef_optype vdefs;
+  v_may_def_optype v_may_defs;
+  v_must_def_optype v_must_defs;
   use_optype uses;
   def_optype defs;
   unsigned x;
@@ -383,16 +384,26 @@ create_ssa_var_map (int flags)
 #endif
 	    }
 
-	  vdefs = VDEF_OPS (ann);
-	  for (x = 0; x < NUM_VDEFS (vdefs); x++)
+	  v_may_defs = V_MAY_DEF_OPS (ann);
+	  for (x = 0; x < NUM_V_MAY_DEFS (v_may_defs); x++)
 	    {
-	      tree var = VDEF_OP (vdefs, x);
+	      tree var = V_MAY_DEF_OP (v_may_defs, x);
 	      set_is_used (var);
 
 #if defined ENABLE_CHECKING
 	      SET_BIT (used_in_virtual_ops, var_ann (SSA_NAME_VAR (var))->uid);
 #endif
 	    }
+	    
+	  v_must_defs = V_MUST_DEF_OPS (ann);
+	  for (x = 0; x < NUM_V_MUST_DEFS (v_must_defs); x++)
+	    {
+	      tree var = V_MUST_DEF_OP (v_must_defs, x);
+	      set_is_used (var);
+#if defined ENABLE_CHECKING
+	      SET_BIT (used_in_virtual_ops, var_ann (SSA_NAME_VAR (var))->uid);
+#endif
+	    }	    
 	}
     }
 
Index: tree-ssa-loop.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-ssa-loop.c,v
retrieving revision 2.1
diff -c -p -u -p -r2.1 tree-ssa-loop.c
--- tree-ssa-loop.c	13 May 2004 06:39:49 -0000	2.1
+++ tree-ssa-loop.c	27 May 2004 18:32:55 -0000
@@ -104,8 +104,9 @@ mark_defs_for_rewrite (basic_block bb)
   block_stmt_iterator bsi;
   stmt_ann_t ann;
   def_optype defs;
-  vdef_optype vdefs;
+  v_may_def_optype v_may_defs;
   vuse_optype vuses;
+  v_must_def_optype v_must_defs;
   unsigned i;
 
   for (stmt = phi_nodes (bb); stmt; stmt = TREE_CHAIN (stmt))
@@ -141,16 +142,23 @@ mark_defs_for_rewrite (basic_block bb)
 	    bitmap_set_bit (vars_to_rename, var_ann (var)->uid);
 	}
 
-      vdefs = VDEF_OPS (ann);
-      for (i = 0; i < NUM_VDEFS (vdefs); i++)
+      v_may_defs = V_MAY_DEF_OPS (ann);
+      for (i = 0; i < NUM_V_MAY_DEFS (v_may_defs); i++)
 	{
-	  var = SSA_NAME_VAR (VDEF_RESULT (vdefs, i));
+	  var = SSA_NAME_VAR (V_MAY_DEF_RESULT (v_may_defs, i));
+	  bitmap_set_bit (vars_to_rename, var_ann (var)->uid);
+	}
+	
+      v_must_defs = V_MUST_DEF_OPS (ann);
+      for (i = 0; i < NUM_V_MUST_DEFS (v_must_defs); i++)
+	{
+	  var = SSA_NAME_VAR (V_MUST_DEF_OP (v_must_defs, i));
 	  bitmap_set_bit (vars_to_rename, var_ann (var)->uid);
 	}
 
       /* We also need to rewrite vuses, since we will copy the statements
 	 and the ssa versions could not be recovered in the copy.  We do
-	 not have to do this for operands of VDEFS explicitly, since
+	 not have to do this for operands of V_MAY_DEFS explicitly, since
 	 they have the same underlying variable as the results.  */
       vuses = VUSE_OPS (ann);
       for (i = 0; i < NUM_VUSES (vuses); i++)
Index: tree-ssa-operands.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-ssa-operands.c,v
retrieving revision 2.3
diff -c -p -u -p -r2.3 tree-ssa-operands.c
--- tree-ssa-operands.c	17 May 2004 21:25:28 -0000	2.3
+++ tree-ssa-operands.c	27 May 2004 18:32:55 -0000
@@ -37,9 +37,12 @@ Boston, MA 02111-1307, USA.  */
 /* By default, operands are loaded.  */
 #define opf_none	0
 
-/* Operand is the target of an assignment expression.  */
+/* Operand is the target of an assignment expression or a call-clobbered variable  */
 #define opf_is_def 	(1 << 0)
 
+/* Operand is the target of an assignment expression.  */
+#define opf_kill_def 	(1 << 2)
+
 /* No virtual operands should be created in the expression.  This is used
    when traversing ADDR_EXPR nodes which have different semantics than
    other expressions.  Inside an ADDR_EXPR node, the only operands that we
@@ -54,27 +57,32 @@ static GTY (()) varray_type build_defs;
 /* Array for building all the use operands.  */
 static GTY (()) varray_type build_uses;
 
-/* Array for building all the vdef operands.  */
-static GTY (()) varray_type build_vdefs;
+/* Array for building all the v_may_def operands.  */
+static GTY (()) varray_type build_v_may_defs;
 
 /* Array for building all the vuse operands.  */
 static GTY (()) varray_type build_vuses;
 
+/* Array for building all the v_must_def operands.  */
+static GTY (()) varray_type build_v_must_defs;
+
 #ifdef ENABLE_CHECKING
 tree check_build_stmt;
 #endif
 
 typedef struct voperands_d 
 {
-  vdef_optype vdef_ops;
+  v_may_def_optype v_may_def_ops;
   vuse_optype vuse_ops;
+  v_must_def_optype v_must_def_ops;
 } *voperands_t;
 
 static void note_addressable (tree, stmt_ann_t);
 static void get_expr_operands (tree, tree *, int, voperands_t);
 static inline void append_def (tree *, tree);
 static inline void append_use (tree *, tree);
-static void append_vdef (tree, tree, voperands_t);
+static void append_v_may_def (tree, tree, voperands_t);
+static void append_v_must_def (tree, tree, voperands_t);
 static void add_call_clobber_ops (tree, voperands_t);
 static void add_call_read_ops (tree, voperands_t);
 static void add_stmt_operand (tree *, tree, int, voperands_t);
@@ -85,8 +93,8 @@ struct freelist_d GTY((chain_next ("%h.n
    struct freelist_d *next;
 };
 
-#define NUM_FREE	4
-static GTY ((length ("NUM_FREE"))) struct freelist_d optype_freelist[NUM_FREE] = { {0}, {0}, {0}, {0} };
+#define NUM_FREE	5
+static GTY ((length ("NUM_FREE"))) struct freelist_d optype_freelist[NUM_FREE] = { {0}, {0}, {0}, {0}, {0} };
 
 
 static inline void *
@@ -155,17 +163,17 @@ allocate_use_optype (unsigned num)
   return use_ops;
 }
 
-static inline vdef_optype
-allocate_vdef_optype (unsigned num)
+static inline v_may_def_optype
+allocate_v_may_def_optype (unsigned num)
 {
-  vdef_optype vdef_ops;
+  v_may_def_optype v_may_def_ops;
   unsigned size;
-  size = sizeof (struct vdef_optype_d) + sizeof (tree) * ((num * 2) - 1);
-  vdef_ops = check_optype_freelist (num * 2);
-  if (!vdef_ops)
-    vdef_ops =  ggc_alloc (size);
-  vdef_ops->num_vdefs = num;
-  return vdef_ops;
+  size = sizeof (struct v_may_def_optype_d) + sizeof (tree) * ((num * 2) - 1);
+  v_may_def_ops = check_optype_freelist (num * 2);
+  if (!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;
 }
 
 static inline vuse_optype
@@ -181,6 +189,19 @@ allocate_vuse_optype (unsigned num)
   return vuse_ops;
 }
 
+static inline v_must_def_optype
+allocate_v_must_def_optype (unsigned num)
+{
+  v_must_def_optype v_must_def_ops;
+  unsigned size;
+  size = sizeof (struct v_must_def_optype_d) + sizeof (tree *) * (num - 1);
+  v_must_def_ops = check_optype_freelist (num);
+  if (!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;
+}
+
 static inline void
 free_uses (use_optype *uses, bool dealloc)
 {
@@ -215,13 +236,24 @@ free_vuses (vuse_optype *vuses, bool dea
 }
 
 static inline void
-free_vdefs (vdef_optype *vdefs, bool dealloc)
+free_v_may_defs (v_may_def_optype *v_may_defs, bool dealloc)
+{
+  if (*v_may_defs)
+    {
+      if (dealloc)
+	add_optype_freelist (*v_may_defs, (*v_may_defs)->num_v_may_defs);
+      *v_may_defs = NULL;
+    }
+}
+
+static inline void
+free_v_must_defs (v_must_def_optype *v_must_defs, bool dealloc)
 {
-  if (*vdefs)
+  if (*v_must_defs)
     {
       if (dealloc)
-	add_optype_freelist (*vdefs, (*vdefs)->num_vdefs);
-      *vdefs = NULL;
+	add_optype_freelist (*v_must_defs, (*v_must_defs)->num_v_must_defs);
+      *v_must_defs = NULL;
     }
 }
 
@@ -236,15 +268,24 @@ remove_vuses (tree stmt)
 }
 
 void
-remove_vdefs (tree stmt)
+remove_v_may_defs (tree stmt)
 {
   stmt_ann_t ann;
 
   ann = stmt_ann (stmt);
   if (ann)
-    free_vdefs (&(ann->vdef_ops), true);
+    free_v_may_defs (&(ann->v_may_def_ops), true);
 }
 
+void
+remove_v_must_defs (tree stmt)
+{
+  stmt_ann_t ann;
+
+  ann = stmt_ann (stmt);
+  if (ann)
+    free_v_must_defs (&(ann->v_must_def_ops), true);
+}
 
 void
 init_ssa_operands (void)
@@ -253,8 +294,9 @@ init_ssa_operands (void)
 
   VARRAY_TREE_PTR_INIT (build_defs, 5, "build defs");
   VARRAY_TREE_PTR_INIT (build_uses, 10, "build uses");
-  VARRAY_TREE_INIT (build_vdefs, 10, "build vdefs");
+  VARRAY_TREE_INIT (build_v_may_defs, 10, "build v_may_defs");
   VARRAY_TREE_INIT (build_vuses, 10, "build vuses");
+  VARRAY_TREE_INIT (build_v_must_defs, 10, "build v_must_defs");
 
   for (x = 0; x < NUM_FREE; x++)
     optype_freelist[x].next = NULL;
@@ -328,29 +370,29 @@ finalize_ssa_uses (tree stmt)
 }
 
 static void
-finalize_ssa_vdefs (tree stmt)
+finalize_ssa_v_may_defs (tree stmt)
 {
   unsigned num, x;
-  vdef_optype vdef_ops;
+  v_may_def_optype v_may_def_ops;
   stmt_ann_t ann;
 
-  num = VARRAY_ACTIVE_SIZE (build_vdefs);
+  num = VARRAY_ACTIVE_SIZE (build_v_may_defs);
   if (num == 0)
     return;
 
 #ifdef ENABLE_CHECKING
-  /* VDEFs must be entered in pairs of result/uses.  */
+  /* V_MAY_DEFs must be entered in pairs of result/uses.  */
   if (num % 2 != 0)
     abort();
 #endif
 
-  vdef_ops = allocate_vdef_optype (num / 2);
+  v_may_def_ops = allocate_v_may_def_optype (num / 2);
   for (x = 0; x < num; x++)
-    vdef_ops->vdefs[x] = VARRAY_TREE (build_vdefs, x);
-  VARRAY_CLEAR (build_vdefs);
+    v_may_def_ops->v_may_defs[x] = VARRAY_TREE (build_v_may_defs, x);
+  VARRAY_CLEAR (build_v_may_defs);
 
   ann = stmt_ann (stmt);
-  ann->vdef_ops = vdef_ops;
+  ann->v_may_def_ops = v_may_def_ops;
 }
 
 static inline void
@@ -359,12 +401,12 @@ finalize_ssa_vuses (tree stmt)
   unsigned num, x;
   stmt_ann_t ann;
   vuse_optype vuse_ops;
-  vdef_optype vdefs;
+  v_may_def_optype v_may_defs;
 
 #ifdef ENABLE_CHECKING
-  if (VARRAY_ACTIVE_SIZE (build_vdefs) > 0)
+  if (VARRAY_ACTIVE_SIZE (build_v_may_defs) > 0)
     {
-      fprintf (stderr, "Please finalize VDEFs before finalize VUSES.\n");
+      fprintf (stderr, "Please finalize V_MAY_DEFs before finalize VUSES.\n");
       abort ();
     }
 #endif
@@ -374,42 +416,42 @@ finalize_ssa_vuses (tree stmt)
     return;
 
   /* Remove superfluous VUSE operands.  If the statement already has a
-   VDEF operation for a variable 'a', then a VUSE for 'a' is not
-   needed because VDEFs imply a VUSE of the variable.  For instance,
+   V_MAY_DEF operation for a variable 'a', then a VUSE for 'a' is not
+   needed because V_MAY_DEFs imply a VUSE of the variable.  For instance,
    suppose that variable 'a' is aliased:
 
 	      # VUSE <a_2>
-	      # a_3 = VDEF <a_2>
+	      # a_3 = V_MAY_DEF <a_2>
 	      a = a + 1;
 
-  The VUSE <a_2> is superfluous because it is implied by the VDEF
+  The VUSE <a_2> is superfluous because it is implied by the V_MAY_DEF
   operation.  */
 
   ann = stmt_ann (stmt);
-  vdefs = VDEF_OPS (ann);
-  if (NUM_VDEFS (vdefs) > 0)
+  v_may_defs = V_MAY_DEF_OPS (ann);
+  if (NUM_V_MAY_DEFS (v_may_defs) > 0)
     {
       size_t i, j;
       for (i = 0; i < VARRAY_ACTIVE_SIZE (build_vuses); i++)
 	{
 	  bool found = false;
-	  for (j = 0; j < NUM_VDEFS (vdefs); j++)
+	  for (j = 0; j < NUM_V_MAY_DEFS (v_may_defs); j++)
 	    {
-	      tree vuse_var, vdef_var;
+	      tree vuse_var, v_may_def_var;
 	      tree vuse = VARRAY_TREE (build_vuses, i);
-	      tree vdef = VDEF_OP (vdefs, j);
+	      tree v_may_def = V_MAY_DEF_OP (v_may_defs, j);
 
 	      if (TREE_CODE (vuse) == SSA_NAME)
 		vuse_var = SSA_NAME_VAR (vuse);
 	      else
 		vuse_var = vuse;
 
-	      if (TREE_CODE (vdef) == SSA_NAME)
-		vdef_var = SSA_NAME_VAR (vdef);
+	      if (TREE_CODE (v_may_def) == SSA_NAME)
+		v_may_def_var = SSA_NAME_VAR (v_may_def);
 	      else
-		vdef_var = vdef;
+		v_may_def_var = v_may_def;
 
-	    if (vuse_var == vdef_var)
+	    if (vuse_var == v_may_def_var)
 	      {
 		found = true;
 		break;
@@ -450,6 +492,32 @@ finalize_ssa_vuses (tree stmt)
   ann->vuse_ops = vuse_ops;
 }
 
+static void
+finalize_ssa_v_must_defs (tree stmt)
+{
+  unsigned num, x;
+  stmt_ann_t ann;
+  v_must_def_optype v_must_def_ops;
+
+  num = VARRAY_ACTIVE_SIZE (build_v_must_defs);
+  if (num == 0)
+    return;
+
+#ifdef ENABLE_CHECKING
+  /* There should only be a single V_MUST_DEF per assignment.  */
+  if (TREE_CODE (stmt) == MODIFY_EXPR && num > 1)
+    abort ();
+#endif
+
+  v_must_def_ops = allocate_v_must_def_optype (num);
+  for (x = 0; x < num ; x++)
+    v_must_def_ops->v_must_defs[x] = VARRAY_TREE (build_v_must_defs, x);
+  VARRAY_POP_ALL (build_v_must_defs);
+
+  ann = stmt_ann (stmt);
+  ann->v_must_def_ops = v_must_def_ops;
+}
+
 extern void
 finalize_ssa_stmt_operands (tree stmt)
 {
@@ -460,7 +528,8 @@ finalize_ssa_stmt_operands (tree stmt)
 
   finalize_ssa_defs (stmt);
   finalize_ssa_uses (stmt);
-  finalize_ssa_vdefs (stmt);
+  finalize_ssa_v_must_defs (stmt);
+  finalize_ssa_v_may_defs (stmt);
   finalize_ssa_vuses (stmt);
 
 #ifdef ENABLE_CHECKING
@@ -476,7 +545,8 @@ verify_start_operands (tree stmt ATTRIBU
   if (VARRAY_ACTIVE_SIZE (build_defs) > 0 
       || VARRAY_ACTIVE_SIZE (build_uses) > 0
       || VARRAY_ACTIVE_SIZE (build_vuses) > 0
-      || VARRAY_ACTIVE_SIZE (build_vdefs) > 0)
+      || VARRAY_ACTIVE_SIZE (build_v_may_defs) > 0
+      || VARRAY_ACTIVE_SIZE (build_v_must_defs) > 0)
     abort ();
   if (check_build_stmt != NULL)
     abort();
@@ -517,7 +587,7 @@ append_use (tree *use_p, tree stmt ATTRI
    operands.  */
 
 static void
-append_vdef (tree var, tree stmt, voperands_t prev_vops)
+append_v_may_def (tree var, tree stmt, voperands_t prev_vops)
 {
   stmt_ann_t ann;
   size_t i;
@@ -532,9 +602,9 @@ append_vdef (tree var, tree stmt, vopera
 
   /* Don't allow duplicate entries.  */
 
-  for (i = 0; i < VARRAY_ACTIVE_SIZE (build_vdefs); i += 2)
+  for (i = 0; i < VARRAY_ACTIVE_SIZE (build_v_may_defs); i += 2)
     {
-      tree result = VARRAY_TREE (build_vdefs, i);
+      tree result = VARRAY_TREE (build_v_may_defs, i);
       if (var == result
 	  || (TREE_CODE (result) == SSA_NAME
 	      && var == SSA_NAME_VAR (result)))
@@ -542,32 +612,32 @@ append_vdef (tree var, tree stmt, vopera
     }
 
   /* If the statement already had virtual definitions, see if any of the
-     existing VDEFs matches VAR.  If so, re-use it, otherwise add a new
-     VDEF for VAR.  */
+     existing V_MAY_DEFs matches VAR.  If so, re-use it, otherwise add a new
+     V_MAY_DEF for VAR.  */
   result = NULL_TREE;
   source = NULL_TREE;
   if (prev_vops)
-    for (i = 0; i < NUM_VDEFS (prev_vops->vdef_ops); i++)
+    for (i = 0; i < NUM_V_MAY_DEFS (prev_vops->v_may_def_ops); i++)
       {
-	result = VDEF_RESULT (prev_vops->vdef_ops, i);
+	result = V_MAY_DEF_RESULT (prev_vops->v_may_def_ops, i);
 	if (result == var
 	    || (TREE_CODE (result) == SSA_NAME
 		&& SSA_NAME_VAR (result) == var))
 	  {
-	    source = VDEF_OP (prev_vops->vdef_ops, i);
+	    source = V_MAY_DEF_OP (prev_vops->v_may_def_ops, i);
 	    break;
 	  }
       }
 
-  /* If no previous VDEF operand was found for VAR, create one now.  */
+  /* If no previous V_MAY_DEF operand was found for VAR, create one now.  */
   if (source == NULL_TREE)
     {
       result = var;
       source = var;
     }
 
-  VARRAY_PUSH_TREE (build_vdefs, result);
-  VARRAY_PUSH_TREE (build_vdefs, source);
+  VARRAY_PUSH_TREE (build_v_may_defs, result);
+  VARRAY_PUSH_TREE (build_v_may_defs, source);
 }
 
 
@@ -626,6 +696,61 @@ append_vuse (tree var, tree stmt, vopera
   VARRAY_PUSH_TREE (build_vuses, var);
 }
 
+/* Add VAR to the list of virtual must definitions for STMT.  If PREV_VOPS
+   is not NULL, the existing entries are preserved and no new entries are
+   added here.  This is done to preserve the SSA numbering of virtual
+   operands.  */
+
+static void
+append_v_must_def (tree var, tree stmt, voperands_t prev_vops)
+{
+  stmt_ann_t ann;
+  size_t i;
+  bool found;
+  tree v_must_def;
+
+#ifdef ENABLE_CHECKING
+  if (check_build_stmt != stmt)
+    abort();
+#endif
+
+  ann = stmt_ann (stmt);
+
+  /* Don't allow duplicate entries.  */
+  for (i = 0; i < VARRAY_ACTIVE_SIZE (build_v_must_defs); i++)
+    {
+      tree v_must_def_var = VARRAY_TREE (build_v_must_defs, i);
+      if (var == v_must_def_var
+	  || (TREE_CODE (v_must_def_var) == SSA_NAME
+	      && var == SSA_NAME_VAR (v_must_def_var)))
+	return;
+    }
+
+  /* If the statement already had virtual must defs, see if any of the
+     existing V_MUST_DEFs matches VAR.  If so, re-use it, otherwise add a new
+     V_MUST_DEF for VAR.  */
+  found = false;
+  v_must_def = NULL_TREE;
+  if (prev_vops)
+    for (i = 0; i < NUM_V_MUST_DEFS (prev_vops->v_must_def_ops); i++)
+      {
+	v_must_def = V_MUST_DEF_OP (prev_vops->v_must_def_ops, i);
+	if (v_must_def == var
+	    || (TREE_CODE (v_must_def) == SSA_NAME
+		&& SSA_NAME_VAR (v_must_def) == var))
+	  {
+	    found = true;
+	    break;
+	  }
+      }
+
+  /* If VAR existed already in PREV_VOPS, re-use it.  */
+  if (found)
+    var = v_must_def;
+
+  VARRAY_PUSH_TREE (build_v_must_defs, var);
+}
+
 
 /* External entry point which by-passes the previous vops mechanism.  */
 void
@@ -676,12 +801,14 @@ get_stmt_operands (tree stmt)
 
   /* Before removing existing virtual operands, save them in PREV_VOPS so 
      that we can re-use their SSA versions.  */
-  prev_vops.vdef_ops = VDEF_OPS (ann);
+  prev_vops.v_may_def_ops = V_MAY_DEF_OPS (ann);
   prev_vops.vuse_ops = VUSE_OPS (ann);
+  prev_vops.v_must_def_ops = V_MUST_DEF_OPS (ann);
 
   /* Dont free the previous values to memory since we're still using them.  */
-  free_vdefs (&(ann->vdef_ops), false);
+  free_v_may_defs (&(ann->v_may_def_ops), false);
   free_vuses (&(ann->vuse_ops), false);
+  free_v_must_defs (&(ann->v_must_def_ops), false);
 
   start_ssa_stmt_operands (stmt);
 
@@ -690,7 +817,13 @@ get_stmt_operands (tree stmt)
     {
     case MODIFY_EXPR:
       get_expr_operands (stmt, &TREE_OPERAND (stmt, 1), opf_none, &prev_vops);
-      get_expr_operands (stmt, &TREE_OPERAND (stmt, 0), opf_is_def, &prev_vops);
+      if (TREE_CODE (TREE_OPERAND (stmt, 0)) == ARRAY_REF 
+          || TREE_CODE (TREE_OPERAND (stmt, 0)) == COMPONENT_REF
+	  || TREE_CODE (TREE_OPERAND (stmt, 0)) == REALPART_EXPR
+	  || TREE_CODE (TREE_OPERAND (stmt, 0)) == IMAGPART_EXPR)
+        get_expr_operands (stmt, &TREE_OPERAND (stmt, 0), opf_is_def, &prev_vops);
+      else
+        get_expr_operands (stmt, &TREE_OPERAND (stmt, 0), opf_is_def | opf_kill_def, &prev_vops);
       break;
 
     case COND_EXPR:
@@ -792,8 +925,9 @@ get_stmt_operands (tree stmt)
   finalize_ssa_stmt_operands (stmt);
 
   /* Now free the previous virtual ops to memory.  */
-  free_vdefs (&(prev_vops.vdef_ops), true);
+  free_v_may_defs (&(prev_vops.v_may_def_ops), true);
   free_vuses (&(prev_vops.vuse_ops), true);
+  free_v_must_defs (&(prev_vops.v_must_def_ops), true);
 
   /* Clear the modified bit for STMT.  Subsequent calls to
      get_stmt_operands for this statement will do nothing until the
@@ -806,7 +940,7 @@ get_stmt_operands (tree stmt)
 
 /* Recursively scan the expression pointed by EXPR_P in statement STMT.
    FLAGS is one of the OPF_* constants modifying how to interpret the
-   operands found.  PREV_VOPS is as in append_vdef and append_vuse.  */
+   operands found.  PREV_VOPS is as in append_v_may_def and append_vuse.  */
 
 static void
 get_expr_operands (tree stmt, tree *expr_p, int flags, voperands_t prev_vops)
@@ -1053,7 +1187,13 @@ get_expr_operands (tree stmt, tree *expr
   if (code == MODIFY_EXPR)
     {
       get_expr_operands (stmt, &TREE_OPERAND (expr, 1), opf_none, prev_vops);
-      get_expr_operands (stmt, &TREE_OPERAND (expr, 0), opf_is_def, prev_vops);
+      if (TREE_CODE (TREE_OPERAND (expr, 0)) == ARRAY_REF 
+          || TREE_CODE (TREE_OPERAND (expr, 0)) == COMPONENT_REF
+	  || TREE_CODE (TREE_OPERAND (expr, 0)) == REALPART_EXPR
+	  || TREE_CODE (TREE_OPERAND (expr, 0)) == IMAGPART_EXPR)
+        get_expr_operands (stmt, &TREE_OPERAND (expr, 0), opf_is_def, prev_vops);
+      else
+        get_expr_operands (stmt, &TREE_OPERAND (expr, 0), opf_is_def | opf_kill_def, prev_vops);
       return;
     }
 
@@ -1104,7 +1244,7 @@ get_expr_operands (tree stmt, tree *expr
    operands.
 
    PREV_VOPS is used when adding virtual operands to statements that
-      already had them (See append_vdef and append_vuse).  */
+      already had them (See append_v_may_def and append_vuse).  */
 
 static void
 add_stmt_operand (tree *var_p, tree stmt, int flags, voperands_t prev_vops)
@@ -1193,9 +1333,19 @@ add_stmt_operand (tree *var_p, tree stmt
 	  /* The variable is not aliased or it is an alias tag.  */
 	  if (flags & opf_is_def)
 	    {
-	      append_vdef (var, stmt, prev_vops);
 	      if (v_ann->is_alias_tag)
-		s_ann->makes_aliased_stores = 1;
+	        {
+		  /* Alias tagged vars get regular V_MAY_DEF  */
+		  s_ann->makes_aliased_stores = 1;
+		  append_v_may_def (var, stmt, prev_vops);
+		}
+	      else if ((flags & opf_kill_def) && v_ann->mem_tag_kind == NOT_A_TAG)
+	        /* V_MUST_DEF for non-aliased non-GIMPLE register variable 
+		   definitions. Avoid memory tags.  */
+	        append_v_must_def (var, stmt, prev_vops);
+	      else
+	        /* Call-clobbered variables & memory tags get V_MAY_DEF  */
+		append_v_may_def (var, stmt, prev_vops);
 	    }
 	  else
 	    {
@@ -1220,10 +1370,10 @@ add_stmt_operand (tree *var_p, tree stmt
 		 references to the members of the variable's alias set.
 		 This fixes the bug in gcc.c-torture/execute/20020503-1.c.  */
 	      if (v_ann->is_alias_tag)
-		append_vdef (var, stmt, prev_vops);
+		append_v_may_def (var, stmt, prev_vops);
 
 	      for (i = 0; i < VARRAY_ACTIVE_SIZE (aliases); i++)
-		append_vdef (VARRAY_TREE (aliases, i), stmt, prev_vops);
+		append_v_may_def (VARRAY_TREE (aliases, i), stmt, prev_vops);
 
 	      s_ann->makes_aliased_stores = 1;
 	    }
@@ -1267,7 +1417,7 @@ add_call_clobber_ops (tree stmt, voperan
      call-clobbered variables.  */
   stmt_ann (stmt)->makes_clobbering_call = true;
 
-  /* If we had created .GLOBAL_VAR earlier, use it.  Otherwise, add a VDEF
+  /* If we had created .GLOBAL_VAR earlier, use it.  Otherwise, add a V_MAY_DEF
      operand for every call clobbered variable.  See compute_may_aliases for
      the heuristic used to decide whether to create .GLOBAL_VAR or not.  */
   if (global_var)
@@ -1280,7 +1430,7 @@ add_call_clobber_ops (tree stmt, voperan
 	{
 	  tree var = referenced_var (i);
 
-	  /* If VAR is read-only, don't add a VDEF, just a VUSE operand.  */
+	  /* If VAR is read-only, don't add a V_MAY_DEF, just a VUSE operand.  */
 	  if (!TREE_READONLY (var))
 	    add_stmt_operand (&var, stmt, opf_is_def, prev_vops);
 	  else
Index: tree-ssa-operands.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-ssa-operands.h,v
retrieving revision 2.1
diff -c -p -u -p -r2.1 tree-ssa-operands.h
--- tree-ssa-operands.h	13 May 2004 06:39:49 -0000	2.1
+++ tree-ssa-operands.h	27 May 2004 18:32:55 -0000
@@ -39,13 +39,13 @@ typedef struct use_optype_d GTY(())
 
 typedef use_optype_t *use_optype;
 
-typedef struct vdef_optype_d GTY(())
+typedef struct v_may_def_optype_d GTY(())
 {
-  unsigned num_vdefs; 
-  tree GTY((length ("%h.num_vdefs * 2"))) vdefs[1];
-} vdef_optype_t;
+  unsigned num_v_may_defs; 
+  tree GTY((length ("%h.num_v_may_defs * 2"))) v_may_defs[1];
+} v_may_def_optype_t;
 
-typedef vdef_optype_t *vdef_optype;
+typedef v_may_def_optype_t *v_may_def_optype;
 
 typedef struct vuse_optype_d GTY(()) 
 {
@@ -55,6 +55,14 @@ typedef struct vuse_optype_d GTY(()) 
 
 typedef vuse_optype_t *vuse_optype;
 
+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_must_def_optype_t;
+
+typedef v_must_def_optype_t *v_must_def_optype;
+
 #define USE_OPS(ANN)		get_use_ops (ANN)
 #define STMT_USE_OPS(STMT)	get_use_ops (stmt_ann (STMT))
 #define NUM_USES(OPS)		((OPS) ? (OPS)->num_uses : 0)
@@ -69,13 +77,13 @@ typedef vuse_optype_t *vuse_optype;
 #define DEF_OP(OPS, I)		(*(DEF_OP_PTR ((OPS), (I))))
 
 
-#define VDEF_OPS(ANN)		get_vdef_ops (ANN)
-#define STMT_VDEF_OPS(STMT)	get_vdef_ops (stmt_ann(STMT))
-#define NUM_VDEFS(OPS)		((OPS) ? (OPS)->num_vdefs : 0)
-#define VDEF_RESULT_PTR(OPS, I)	get_vdef_result_ptr ((OPS), (I))
-#define VDEF_RESULT(OPS, I)	(*(VDEF_RESULT_PTR ((OPS), (I))))
-#define VDEF_OP_PTR(OPS, I)	get_vdef_op_ptr ((OPS), (I))
-#define VDEF_OP(OPS, I)		(*(VDEF_OP_PTR ((OPS), (I))))
+#define V_MAY_DEF_OPS(ANN)		get_v_may_def_ops (ANN)
+#define STMT_V_MAY_DEF_OPS(STMT)	get_v_may_def_ops (stmt_ann(STMT))
+#define NUM_V_MAY_DEFS(OPS)		((OPS) ? (OPS)->num_v_may_defs : 0)
+#define V_MAY_DEF_RESULT_PTR(OPS, I)	get_v_may_def_result_ptr ((OPS), (I))
+#define V_MAY_DEF_RESULT(OPS, I)	(*(V_MAY_DEF_RESULT_PTR ((OPS), (I))))
+#define V_MAY_DEF_OP_PTR(OPS, I)	get_v_may_def_op_ptr ((OPS), (I))
+#define V_MAY_DEF_OP(OPS, I)		(*(V_MAY_DEF_OP_PTR ((OPS), (I))))
 
 
 #define VUSE_OPS(ANN)		get_vuse_ops (ANN)
@@ -85,6 +93,12 @@ typedef vuse_optype_t *vuse_optype;
 #define VUSE_OP(OPS, I)  	(*(VUSE_OP_PTR ((OPS), (I))))
 
 
+#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)		(*(V_MUST_DEF_OP_PTR ((OPS), (I))))
+
 extern void init_ssa_operands (void);
 extern void fini_ssa_operands (void);
 extern void verify_start_operands (tree);
@@ -92,6 +106,7 @@ extern void finalize_ssa_stmt_operands (
 void add_vuse (tree, tree);
 extern void get_stmt_operands (tree);
 extern void remove_vuses (tree);
-extern void remove_vdefs (tree);
+extern void remove_v_may_defs (tree);
+extern void remove_v_must_defs (tree);
 
 #endif  /* GCC_TREE_SSA_OPERANDS_H  */
Index: tree-ssa-pre.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-ssa-pre.c,v
retrieving revision 2.3
diff -c -p -u -p -r2.3 tree-ssa-pre.c
--- tree-ssa-pre.c	14 May 2004 02:29:23 -0000	2.3
+++ tree-ssa-pre.c	27 May 2004 18:32:55 -0000
@@ -1312,7 +1312,8 @@ subst_phis (struct expr_info *ei, tree Z
   else
     {
       remove_vuses (stmt_copy);
-      remove_vdefs (stmt_copy);
+      remove_v_may_defs (stmt_copy);
+      remove_v_must_defs (stmt_copy);
     }
 
   if (pred->index < n_phi_preds)
@@ -3016,13 +3017,16 @@ process_left_occs_and_kills (varray_type
 {
   size_t i, j, k;
   
-  stmt_ann_t ann = stmt_ann (expr);
-  vdef_optype vdefs;
+  v_may_def_optype v_may_defs;
+  v_must_def_optype v_must_defs;
   vuse_optype vuses;
   def_optype defs;
-  defs = DEF_OPS (ann);
-  vdefs = VDEF_OPS (ann);
-  if (NUM_DEFS (defs) == 0 && NUM_VDEFS (vdefs) == 0)
+  defs = STMT_DEF_OPS (expr);
+  v_may_defs = STMT_V_MAY_DEF_OPS (expr);
+  v_must_defs = STMT_V_MUST_DEF_OPS (expr);
+  if (NUM_DEFS (defs) == 0 
+      && NUM_V_MAY_DEFS (v_may_defs) == 0 
+      && NUM_V_MUST_DEFS (v_must_defs) == 0)
     return;
 
   for (j = 0; j < VARRAY_ACTIVE_SIZE (bexprs); j++)
@@ -3052,19 +3056,36 @@ process_left_occs_and_kills (varray_type
 	    }
 	}
       
-      /* If we VDEF the VUSE of the expression, it's also a left
+      /* If we virtually define the variable itself,
+	 it's a left occurrence.  */
+      for (i = 0; i < NUM_V_MUST_DEFS (v_must_defs); i++)
+	{
+	  if (names_match_p (V_MUST_DEF_OP (v_must_defs, i), ei->expr))    
+	    {
+	      if (TREE_CODE (expr) == ASM_EXPR)
+		{
+		  ei->loadpre_cand = false;
+		  continue;
+		}
+	      VARRAY_PUSH_TREE (ei->lefts, expr);
+	      VARRAY_PUSH_TREE (ei->occurs, NULL);
+	      VARRAY_PUSH_TREE (ei->kills, NULL);
+	    }
+	}
+      
+      /* If we V_MAY_DEF the VUSE of the expression, it's also a left
 	 occurrence.  */
       random_occur = VARRAY_TREE (ei->occurs, 0);
       ann = stmt_ann (random_occur);
       vuses = VUSE_OPS (ann);
-      if (NUM_VDEFS (vdefs) != 0)
+      if (NUM_V_MAY_DEFS (v_may_defs) != 0)
 	{
 	  for (k = 0; k < NUM_VUSES (vuses); k++)
 	    {
 	      vuse_name = VUSE_OP (vuses, k);
-	      for (i = 0; i < NUM_VDEFS (vdefs); i++)
+	      for (i = 0; i < NUM_V_MAY_DEFS (v_may_defs); i++)
 		{
-		  if (names_match_p (VDEF_OP (vdefs, i), vuse_name))
+		  if (names_match_p (V_MAY_DEF_OP (v_may_defs, i), vuse_name))
 		    {
 		      VARRAY_PUSH_TREE (ei->lefts, expr);
 		      VARRAY_PUSH_TREE (ei->occurs, NULL);
Index: tree-tailcall.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-tailcall.c,v
retrieving revision 2.3
diff -c -p -u -p -r2.3 tree-tailcall.c
--- tree-tailcall.c	15 May 2004 09:39:29 -0000	2.3
+++ tree-tailcall.c	27 May 2004 18:32:55 -0000
@@ -391,7 +391,8 @@ find_tail_calls (basic_block bb, struct 
 
       /* If the statement has virtual operands, fail.  */
       ann = stmt_ann (stmt);
-      if (NUM_VDEFS (VDEF_OPS (ann))
+      if (NUM_V_MAY_DEFS (V_MAY_DEF_OPS (ann))
+          || NUM_V_MUST_DEFS (V_MUST_DEF_OPS (ann))
 	  || NUM_VUSES (VUSE_OPS (ann)))
 	return;
     }
@@ -644,7 +645,7 @@ eliminate_tail_call (struct tailcall *t)
   edge e;
   tree phi;
   stmt_ann_t ann;
-  vdef_optype vdefs;
+  v_may_def_optype v_may_defs;
   unsigned i;
 
   stmt = bsi_stmt (t->call_bsi);
@@ -696,10 +697,10 @@ eliminate_tail_call (struct tailcall *t)
     }
 
   /* Add phi nodes for the call clobbered variables.  */
-  vdefs = VDEF_OPS (ann);
-  for (i = 0; i < NUM_VDEFS (vdefs); i++)
+  v_may_defs = V_MAY_DEF_OPS (ann);
+  for (i = 0; i < NUM_V_MAY_DEFS (v_may_defs); i++)
     {
-      param = SSA_NAME_VAR (VDEF_RESULT (vdefs, i));
+      param = SSA_NAME_VAR (V_MAY_DEF_RESULT (v_may_defs, i));
       for (phi = phi_nodes (first); phi; phi = TREE_CHAIN (phi))
 	if (param == SSA_NAME_VAR (PHI_RESULT (phi)))
 	  break;
@@ -721,7 +722,7 @@ eliminate_tail_call (struct tailcall *t)
 	    abort ();
 	}
 
-      add_phi_arg (&phi, VDEF_OP (vdefs, i), e);
+      add_phi_arg (&phi, V_MAY_DEF_OP (v_may_defs, i), e);
     }
 
   /* Update the values of accumulators.  */
Index: testsuite/gcc.dg/tree-ssa/20031015-1.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/gcc.dg/tree-ssa/20031015-1.c,v
retrieving revision 1.2
diff -c -p -u -p -r1.2 20031015-1.c
--- testsuite/gcc.dg/tree-ssa/20031015-1.c	13 May 2004 06:40:51 -0000	1.2
+++ testsuite/gcc.dg/tree-ssa/20031015-1.c	27 May 2004 18:32:55 -0000
@@ -13,4 +13,4 @@ main(void)
   return 0;
 }
 
-/* { dg-final { scan-tree-dump-times "VDEF" 2 "alias" } } */
+/* { dg-final { scan-tree-dump-times "V_MAY_DEF" 2 "alias" } } */
Index: testsuite/gcc.dg/tree-ssa/20040517-1.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/gcc.dg/tree-ssa/20040517-1.c,v
retrieving revision 1.1
diff -c -p -u -p -r1.1 20040517-1.c
--- testsuite/gcc.dg/tree-ssa/20040517-1.c	17 May 2004 21:25:32 -0000	1.1
+++ testsuite/gcc.dg/tree-ssa/20040517-1.c	27 May 2004 18:32:55 -0000
@@ -16,5 +16,5 @@ void bar (void) 
    malloc functions may clobber global memory.  Only the function result
    does not alias any other pointer.
    Hence, we must have a VDEF for a before and after the call to foo().  */
-/* { dg-final { scan-tree-dump-times "VDEF" 2 "ssa"} } */
+/* { dg-final { scan-tree-dump-times "V_MAY_DEF" 1 "ssa"} } */
 

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH] Splitting of virtual definitions (aka. V_MUST_DEF)
  2004-06-07 14:59 [PATCH] Splitting of virtual definitions (aka. V_MUST_DEF) Brian Booth
@ 2004-06-07 18:34 ` Geert Bosch
  2004-06-08  6:54   ` Jeffrey A Law
  2004-06-08 13:56 ` Diego Novillo
  2004-06-09 23:37 ` Diego Novillo
  2 siblings, 1 reply; 13+ messages in thread
From: Geert Bosch @ 2004-06-07 18:34 UTC (permalink / raw)
  To: Brian Booth; +Cc: GCC-Patches


On Jun 7, 2004, at 09:45, Brian Booth wrote:
>         WITH_PATCH      WITHOUT_PATCH
>
> real    48m24.896s      48m18.499s
> user    37m57.030s      37m37.460s
> sys     6m10.790s       6m5.690s
>
> There is a slow down of about six seconds but I feel that this can be
> overcome with future tuning of the optimization passes to take 
> advantage
> of the V_MUST_DEF construct (dse for example).

It is 25 seconds, 20 seconds in user time and 5 for the system.
That seems like a very large increase, which would need some
more justification.

   -Geert

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH] Splitting of virtual definitions (aka. V_MUST_DEF)
  2004-06-07 18:34 ` Geert Bosch
@ 2004-06-08  6:54   ` Jeffrey A Law
  2004-06-08  8:56     ` Geert Bosch
  0 siblings, 1 reply; 13+ messages in thread
From: Jeffrey A Law @ 2004-06-08  6:54 UTC (permalink / raw)
  To: Geert Bosch; +Cc: Brian Booth, GCC-Patches

On Mon, 2004-06-07 at 11:29, Geert Bosch wrote:
> On Jun 7, 2004, at 09:45, Brian Booth wrote:
> >         WITH_PATCH      WITHOUT_PATCH
> >
> > real    48m24.896s      48m18.499s
> > user    37m57.030s      37m37.460s
> > sys     6m10.790s       6m5.690s
> >
> > There is a slow down of about six seconds but I feel that this can be
> > overcome with future tuning of the optimization passes to take 
> > advantage
> > of the V_MUST_DEF construct (dse for example).
> 
> It is 25 seconds, 20 seconds in user time and 5 for the system.
> That seems like a very large increase, which would need some
> more justification.
Having a V_MUST_DEF allows us to do some interest things as it
indicates a more precise level of aliasing information.  ie, it
allows us to say that a highly specific area of memory is going
to be changed.  With that information we can improve redundant
load/store elimination in addition to improving alias analysis.

jeff


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH] Splitting of virtual definitions (aka. V_MUST_DEF)
  2004-06-08  6:54   ` Jeffrey A Law
@ 2004-06-08  8:56     ` Geert Bosch
  2004-06-08 11:07       ` Steven Bosscher
  2004-06-08 17:22       ` Jeffrey A Law
  0 siblings, 2 replies; 13+ messages in thread
From: Geert Bosch @ 2004-06-08  8:56 UTC (permalink / raw)
  To: law; +Cc: Brian Booth, GCC-Patches


On Jun 7, 2004, at 23:08, Jeffrey A Law wrote:
> Having a V_MUST_DEF allows us to do some interest things as it
> indicates a more precise level of aliasing information.  ie, it
> allows us to say that a highly specific area of memory is going
> to be changed.  With that information we can improve redundant
> load/store elimination in addition to improving alias analysis.

I understand, but when we add 3% to compile time as a result
of this, we should have a double look at the data structures
we use. How do other compilers record this data?

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH] Splitting of virtual definitions (aka. V_MUST_DEF)
  2004-06-08  8:56     ` Geert Bosch
@ 2004-06-08 11:07       ` Steven Bosscher
  2004-06-08 18:20         ` Geert Bosch
  2004-06-10 17:29         ` Brian Booth
  2004-06-08 17:22       ` Jeffrey A Law
  1 sibling, 2 replies; 13+ messages in thread
From: Steven Bosscher @ 2004-06-08 11:07 UTC (permalink / raw)
  To: Geert Bosch, law; +Cc: Brian Booth, GCC-Patches

On Tuesday 08 June 2004 06:01, Geert Bosch wrote:
> On Jun 7, 2004, at 23:08, Jeffrey A Law wrote:
> > Having a V_MUST_DEF allows us to do some interest things as it
> > indicates a more precise level of aliasing information.  ie, it
> > allows us to say that a highly specific area of memory is going
> > to be changed.  With that information we can improve redundant
> > load/store elimination in addition to improving alias analysis.
>
> I understand, but when we add 3% to compile time as a result
> of this,

Hi Geert,

First, your math is interesting, but clearly wrong:

Before: 37m37s  -> 2257s
After:  37m57s  -> 2277s
2277/2257 = 1.009, according to my calculator.

So your "3%" is in fact less than 1%, which could be
just noise.

But I think those numbers are pretty irrelevant anyway
since Brian doesn't state if they're averages of, say,
3 runs; and with a system time of more than 6 minutes
I think (well, hope) this was tested on a machine that
was also crunching cycles on something else.


> we should have a double look at the data structures
> we use. How do other compilers record this data?

Andrew Macleod already went over the data structures
we use for SSA operands and what we have now is quite
efficient.

Gr.
Steven


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH] Splitting of virtual definitions (aka. V_MUST_DEF)
  2004-06-07 14:59 [PATCH] Splitting of virtual definitions (aka. V_MUST_DEF) Brian Booth
  2004-06-07 18:34 ` Geert Bosch
@ 2004-06-08 13:56 ` Diego Novillo
  2004-06-10 17:36   ` Brian Booth
  2004-06-09 23:37 ` Diego Novillo
  2 siblings, 1 reply; 13+ messages in thread
From: Diego Novillo @ 2004-06-08 13:56 UTC (permalink / raw)
  To: Brian Booth; +Cc: GCC-Patches, Richard Henderson

On Mon, 2004-06-07 at 09:45, Brian Booth wrote:

> At the moment, VDEFs are used to mark statements that either define a
> non-GIMPLE register or could possibly define one. This patch splits up
> these two cases. It replaces the VDEF with two conceptually different
> constructs: V_MAY_DEF and V_MUST_DEF. These definitions are added to
> statements that may define a non-GIMPLE register and statements that
> have a killing definition of one respectively. Another way of looking at
> it is that the V_MAY_DEF is simply VDEF with a new name while V_MUST_DEF
> is a VDEF without the implied use of its operand. 
> 
Thanks Brian.  I've started looking at the patch now.


>         WITH_PATCH      WITHOUT_PATCH
> 
> real    48m24.896s      48m18.499s
> user    37m57.030s      37m37.460s
> sys     6m10.790s       6m5.690s
> 
Could you test the patch against POOMA
(http://www.tat.physik.uni-tuebingen.de/~rguenth/gcc/monitor-summary.html) and PR8361?  Both in compile time and generated code.


Thanks.  Diego.

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH] Splitting of virtual definitions (aka. V_MUST_DEF)
  2004-06-08  8:56     ` Geert Bosch
  2004-06-08 11:07       ` Steven Bosscher
@ 2004-06-08 17:22       ` Jeffrey A Law
  1 sibling, 0 replies; 13+ messages in thread
From: Jeffrey A Law @ 2004-06-08 17:22 UTC (permalink / raw)
  To: Geert Bosch; +Cc: Brian Booth, GCC-Patches

On Mon, 2004-06-07 at 22:01, Geert Bosch wrote:
> On Jun 7, 2004, at 23:08, Jeffrey A Law wrote:
> > Having a V_MUST_DEF allows us to do some interest things as it
> > indicates a more precise level of aliasing information.  ie, it
> > allows us to say that a highly specific area of memory is going
> > to be changed.  With that information we can improve redundant
> > load/store elimination in addition to improving alias analysis.
> 
> I understand, but when we add 3% to compile time as a result
> of this, we should have a double look at the data structures
> we use. How do other compilers record this data?
Interestingly enough, our handling of virtual operands has been
heavily influenced by the design of SGI's compiler.  V_MUST_DEF
is just another piece we needed to add :-)

jeff  

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH] Splitting of virtual definitions (aka. V_MUST_DEF)
  2004-06-08 11:07       ` Steven Bosscher
@ 2004-06-08 18:20         ` Geert Bosch
  2004-06-10 17:29         ` Brian Booth
  1 sibling, 0 replies; 13+ messages in thread
From: Geert Bosch @ 2004-06-08 18:20 UTC (permalink / raw)
  To: Steven Bosscher; +Cc: law, Brian Booth, GCC-Patches

On Jun 8, 2004, at 01:49, Steven Bosscher wrote:
> First, your math is interesting, but clearly wrong:
>
> Before: 37m37s  -> 2257s
> After:  37m57s  -> 2277s
> 2277/2257 = 1.009, according to my calculator.
I stand corrected, even including the system time it is
only 0.95% slower.

   -Geert

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH] Splitting of virtual definitions (aka. V_MUST_DEF)
  2004-06-07 14:59 [PATCH] Splitting of virtual definitions (aka. V_MUST_DEF) Brian Booth
  2004-06-07 18:34 ` Geert Bosch
  2004-06-08 13:56 ` Diego Novillo
@ 2004-06-09 23:37 ` Diego Novillo
  2004-06-10 17:45   ` Brian Booth
  2 siblings, 1 reply; 13+ messages in thread
From: Diego Novillo @ 2004-06-09 23:37 UTC (permalink / raw)
  To: Brian Booth; +Cc: GCC-Patches, Richard Henderson

On Mon, 2004-06-07 at 09:45, Brian Booth wrote:

> 2004-06-07  Brian Booth  <bbooth@redhat.com>
> 
> 	* tree-dfa.c (dfa_stats_d): Add num_v_must_defs and rename
> 	num_vdefs to num_v_may_defs.
> 	(compute_immediate_uses_for_stmt): Rename occurences of vdef
> 	to v_may_def.
> 	(redirect_immediate_uses): Ditto.
> [ ... ]
>
Excellent job.  Thanks!  Only two things before you commit:

     1. Make sure that you don't have long lines wrapping around 80
        columns.
     2. Please modify the documentation in doc/tree-ssa.texi to describe
        V_MUST_DEF and V_MAY_DEF.

After you make those changes, the patch can go in.

Now that we have the infrastructure for must-defs, you can start
thinking about things we could do with them in the existing optimizers.

Did you get a chance of running this through POOMA and DLV?


Thanks.  Diego.

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH] Splitting of virtual definitions (aka. V_MUST_DEF)
  2004-06-08 11:07       ` Steven Bosscher
  2004-06-08 18:20         ` Geert Bosch
@ 2004-06-10 17:29         ` Brian Booth
  1 sibling, 0 replies; 13+ messages in thread
From: Brian Booth @ 2004-06-10 17:29 UTC (permalink / raw)
  To: Steven Bosscher; +Cc: Geert Bosch, law, GCC-Patches

On Tue, 2004-06-08 at 01:49, Steven Bosscher wrote:
> But I think those numbers are pretty irrelevant anyway
> since Brian doesn't state if they're averages of, say,
> 3 runs; and with a system time of more than 6 minutes
> I think (well, hope) this was tested on a machine that
> was also crunching cycles on something else.

Yah, the timing thing was pretty much an afterthought. Here's the
average of three bootstraps on a less busy (albeit slower) test machine:

	WITH PATCH	WITHOUT PATCH
real	102m42.239s	102m25.087s
usr	83m28.630s	83m16.497s
sys	13m54.683s	13m54.940s

These results show a consistent compile time increase of around 0.24%

Brian
---

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH] Splitting of virtual definitions (aka. V_MUST_DEF)
  2004-06-08 13:56 ` Diego Novillo
@ 2004-06-10 17:36   ` Brian Booth
  0 siblings, 0 replies; 13+ messages in thread
From: Brian Booth @ 2004-06-10 17:36 UTC (permalink / raw)
  To: Diego Novillo; +Cc: GCC-Patches, Richard Henderson

On Tue, 2004-06-08 at 08:09, Diego Novillo wrote:
> Could you test the patch against POOMA
> (http://www.tat.physik.uni-tuebingen.de/~rguenth/gcc/monitor-summary.html) 

Here is the average of three runs:

flags: -O2 -funroll-loops -ffast-math

	WITH PATCH	WITHOUT PATCH
real	83m54.488s	79m35.982s
usr	3m38.307s	3m37.057s
sys	0m27.477s	0m24.467s

assembly
code 	8,643,479	8,649,104
size
(bytes)

Ah, thrashing. Anyway, this shows a compile time (usr time) increase of
roughly 0.58% which was fairly consistent over all three runs and a code
size improvement of 0.07%.

> and PR8361? 

Here is the average of three runs:

flags: -O3

	WITH PATCH	WITHOUT PATCH
real	0m21.108s	0m20.944s
usr	0m17.293s	0m17.347s
sys	0m1.470s	0m1.583s

assembly
code 	4139		4139
size
(bytes)

No code size improvement and a slight decrease in compile time (roughly
0.31%). However, since one was not consistently faster than the other
over the three runs, I'm assuming that this is just noise.

Brian
---

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH] Splitting of virtual definitions (aka. V_MUST_DEF)
  2004-06-09 23:37 ` Diego Novillo
@ 2004-06-10 17:45   ` Brian Booth
  2004-06-10 17:50     ` Diego Novillo
  0 siblings, 1 reply; 13+ messages in thread
From: Brian Booth @ 2004-06-10 17:45 UTC (permalink / raw)
  To: Diego Novillo; +Cc: GCC-Patches, Richard Henderson

[-- Attachment #1: Type: text/plain, Size: 471 bytes --]

On Wed, 2004-06-09 at 18:18, Diego Novillo wrote:
> Only two things before you commit:
> 
>      1. Make sure that you don't have long lines wrapping around 80
>         columns.

Done.

>      2. Please modify the documentation in doc/tree-ssa.texi to describe
>         V_MUST_DEF and V_MAY_DEF.

How's this?

Brian
---

2004-06-10  Brian Booth  <bbooth@redhat.com>

	* doc/tree-ssa.texi: Remove references to VDEF and add 
	  descriptions of V_MAY_DEF and V_MUST_DEF.

[-- Attachment #2: doc.patch --]
[-- Type: text/x-patch, Size: 4185 bytes --]

Index: tree-ssa.texi
===================================================================
RCS file: /cvs/gcc/gcc/gcc/doc/tree-ssa.texi,v
retrieving revision 1.2
diff -c -p -u -p -r1.2 tree-ssa.texi
--- tree-ssa.texi	13 May 2004 06:40:27 -0000	1.2
+++ tree-ssa.texi	10 Jun 2004 14:36:23 -0000
@@ -697,8 +697,17 @@ variable @code{b} is completely modified
 variable @code{a}.  Real definition are also known as @dfn{killing
 definitions}.  Similarly, the use of @code{a} reads all its bits.
 
-In contrast, virtual operands represent partial or ambiguous
-references to a variable.  For instance, given
+In contrast, virtual operands are used with variables that can have
+a partial or ambiguous reference. This includes structures, arrays,
+globals, and aliased variables. In these cases, we have two types of
+definitions. For globals, structures, and arrays, we can determine from
+a statement whether a variable of these types has a killing definition. 
+If the variable does, then the statement is marked as having a
+@dfn{must definition} of that variable. However, if a statement is only
+defining a part of the variable (ie. a field in a structure), or if we
+know that a statement might define the variable but we cannot say for sure,
+then we mark that statement as having a @dfn{may definition}.  For 
+instance, given
 
 @smallexample
 @{
@@ -730,8 +739,8 @@ operands, use the @option{-vops} option 
     p = &a;
   else
     p = &b;
-  # a = VDEF <a>
-  # b = VDEF <b>
+  # a = V_MAY_DEF <a>
+  # b = V_MAY_DEF <b>
   *p = 5;
 
   # VUSE <a>
@@ -740,21 +749,21 @@ operands, use the @option{-vops} option 
 @}
 @end smallexample
 
-Notice that @code{VDEF} operands have two copies of the referenced
+Notice that @code{V_MAY_DEF} operands have two copies of the referenced
 variable.  This indicates that this is not a killing definition of
 that variable.  In this case we refer to it as a @dfn{may definition}
 or @dfn{aliased store}.  The presence of the second copy of the
-variable in the @code{VDEF} operand will become important when the
+variable in the @code{V_MAY_DEF} operand will become important when the
 function is converted into SSA form.  This will be used to link all
 the non-killing definitions to prevent optimizations from making
 incorrect assumptions about them.
 
 Operands are collected by @file{tree-ssa-operands.c}.  They are stored
 inside each statement's annotation and can be accessed with
-@code{DEF_OPS}, @code{USE_OPS}, @code{VDEF_OPS} and @code{VUSE_OPS}.
-The following are all the accessor macros available to access USE
-operands.  To access all the other operand arrays, just change the
-name accordingly:
+@code{DEF_OPS}, @code{USE_OPS}, @code{V_MAY_DEF_OPS}, 
+@code{V_MUST_DEF_OPS} and @code{VUSE_OPS}. The following are all the 
+accessor macros available to access USE operands.  To access all the 
+other operand arrays, just change the name accordingly:
 
 @defmac USE_OPS (@var{ann})
 Returns the array of operands used by the statement with annotation
@@ -786,7 +795,8 @@ void
 print_ops (tree stmt)
 @{
   vuse_optype vuses;
-  vdef_optype vdefs;
+  v_may_def_optype v_may_defs;
+  v_must_def_optype v_must_defs;
   def_optype defs;
   use_optype uses;
   stmt_ann_t ann;
@@ -803,9 +813,13 @@ print_ops (tree stmt)
   for (i = 0; i < NUM_USES (uses); i++)
     print_generic_expr (stderr, USE_OP (uses, i), 0);
   
-  vdefs = VDEF_OPS (ann);
-  for (i = 0; i < NUM_VDEFS (vdefs); i++)
-    print_generic_expr (stderr, VDEF_OP (vdefs, i), 0);
+  v_may_defs = V_MAY_DEF_OPS (ann);
+  for (i = 0; i < NUM_V_MAY_DEFS (v_may_defs); i++)
+    print_generic_expr (stderr, V_MAY_DEF_OP (v_may_defs, i), 0);
+
+  v_must_defs = V_MUST_DEF_OPS (ann);
+  for (i = 0; i < NUM_V_MUST_DEFS (v_must_defs); i++)
+    print_generic_expr (stderr, V_MUST_DEF_OP (v_must_defs, i), 0);
   
   vuses = VUSE_OPS (ann);
   for (i = 0; i < NUM_VUSES (vuses); i++)
@@ -1095,11 +1109,11 @@ foo (int i)
     p_6 = &b;
   # p_1 = PHI <p_4(1), p_6(2)>;
 
-  # a_7 = VDEF <a_3>;
-  # b_8 = VDEF <b_5>;
+  # a_7 = V_MAY_DEF <a_3>;
+  # b_8 = V_MAY_DEF <b_5>;
   *p_1 = 3;
 
-  # a_9 = VDEF <a_7>
+  # a_9 = V_MAY_DEF <a_7>
   # VUSE <b_8>
   a_9 = b_8 + 2;
 

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH] Splitting of virtual definitions (aka. V_MUST_DEF)
  2004-06-10 17:45   ` Brian Booth
@ 2004-06-10 17:50     ` Diego Novillo
  0 siblings, 0 replies; 13+ messages in thread
From: Diego Novillo @ 2004-06-10 17:50 UTC (permalink / raw)
  To: Brian Booth; +Cc: GCC-Patches, Richard Henderson

On Thu, 2004-06-10 at 11:38, Brian Booth wrote:

> 	* doc/tree-ssa.texi: Remove references to VDEF and add 
> 	  descriptions of V_MAY_DEF and V_MUST_DEF.
>
Looks good.  Thanks.


Diego.

^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2004-06-10 15:44 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-06-07 14:59 [PATCH] Splitting of virtual definitions (aka. V_MUST_DEF) Brian Booth
2004-06-07 18:34 ` Geert Bosch
2004-06-08  6:54   ` Jeffrey A Law
2004-06-08  8:56     ` Geert Bosch
2004-06-08 11:07       ` Steven Bosscher
2004-06-08 18:20         ` Geert Bosch
2004-06-10 17:29         ` Brian Booth
2004-06-08 17:22       ` Jeffrey A Law
2004-06-08 13:56 ` Diego Novillo
2004-06-10 17:36   ` Brian Booth
2004-06-09 23:37 ` Diego Novillo
2004-06-10 17:45   ` Brian Booth
2004-06-10 17:50     ` Diego Novillo

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).