From 4c124b4c6f4e9017f5682cede57bd84c1129da2a Mon Sep 17 00:00:00 2001
From: Andrew MacLeod <amacleod@redhat.com>
Date: Wed, 25 Aug 2004 21:21:19 +0000
Subject: [PATCH] tree-ssa-operands.h (struct ssa_operand_iterator_d): New.

2004-08-25  Andrew MacLeod  <amacleod@redhat.com>

	* tree-ssa-operands.h (struct ssa_operand_iterator_d): New.  SSA operand
	iterator controlling structure.
	(SSA_OP_USE, SSA_OP_DEF, SSA_OP_VUSE, SSA_OP_VMAYUSE, SSA_OP_VMAYDEF,
	SSA_OP_VMUSTDEF, SSA_OP_VIRTUAL_USES, SSA_OP_VIRTUAL_DEFS,
	SSA_OP_ALL_USES, SSA_OP_ALL_DEFS, SSA_OP_ALL_OPERANDS): New.  Operand
	iterator flags.
	(FOR_EACH_SSA_TREE_OPERAND): New.  Iterate over operands as trees.
	(FOR_EACH_SSA_USE_OPERAND): New.  Iterate over operands as uses.
	(FOR_EACH_SSA_DEF_OPERAND): New.  Iterate over operands as defs.
	(FOR_EACH_SSA_MAYDEF_OPERAND): New.  Iterate over V_MAY_DEFs.
	* tree-ssa-operands.c (NULL_DEF_OPERAND_P, NULL_USE_OPERAND_P): New.
	Empty operand pointers.
	* tree-flow-inline.h (op_iter_done): New.  Return true if finished.
	(op_iter_next_use): New.  Return next use_operand_p.
	(op_iter_next_def): New.  Return next def_operand_p.
	(op_iter_next_tree): New.  Return next operands as a tree.
	(op_iter_init): New.  Initialize an iterator structure.
	(op_iter_init_use): New.  Initialize structure and get the first use.
	(op_iter_init_def): New.  Initialize structure and get the first def.
	(op_iter_init_tree): New.  Initialize structure and get the first tree.
	(op_iter_next_maydef): New.  Return next V_MAY_DEF operands.
	(op_iter_init_maydef): New.  Initialize structure and get the first
	V_MAY_DEF operands.
	* tree-cfg.c (tree_duplicate_bb): Use new operand iterator.
	* tree-dfa.c (compute_immediate_uses_for_stmt,
	redirect_immediate_uses): Use new operand iterator.
	(v_may_defs_disappeared_p, v_must_defs_disappeared_p): Delete.
	(mark_new_vars_to_rename): Use new operand iterator.  Count virtual
	operands instead of using *_disappeared_p routines.
	* tree-into-ssa.c (mark_def_sites, ssa_mark_def_sites, rewrite_stmt,
	ssa_rewrite_stmt): Use new operand iterator.
	* tree-outof-ssa.c (check_replaceable, find_replaceable_in_bb,
	rewrite_trees): Use new operand iterator.
	* tree-pretty-print.c (dump_vops): Use new operand iterator.
	* tree-sra.c (mark_all_v_defs): Use new operand iterator.
	* tree-ssa-alias.c (compute_points_to_and_addr_escape,
	dump_points_to_info): Use new operand iterator.
	* tree-ssa-ccp.c (cp_lattice_meet, visit_stmt, initialize,
	replace_uses_in, replace_vuse_in, likely_value, set_rhs): Use new
	operand iterator.
	* tree-ssa-dce.c (mark_stmt_if_obviously_necessary,
	propagate_necessity): Use new operand iterator.
	* tree-ssa-dom.c (cprop_into_stmt, optimize_stmt): Use operand iterator.
	(register_definitions_for_stmt): Use new operand iterator.  Take stmt as
	a parameter instead of a stmt_ann_t.
	* tree-ssa-live.c (create_ssa_var_map, calculate_live_on_entry,
	build_tree_conflict_graph): Use new operand iterator.
	* tree-ssa-loop-im.c (determine_max_movement, single_reachable_address,
	rewrite_mem_refs): Use new operand iterator.
	* tree-ssa-loop-manip.c (find_uses_to_rename_stmt,
	check_loop_closed_ssa_use): Use new operand iterator.
	* tree-ssa.c (verify_ssa, replace_immediate_uses): Use operand iterator.
	* tree-ssanames.c (release_defs): Use new operand iterator.
	* tree-vectorizer.c (vect_create_data_ref): Use new operand iterator.

From-SVN: r86583
---
 gcc/ChangeLog             |  57 +++++++++
 gcc/tree-cfg.c            |  20 +---
 gcc/tree-dfa.c            | 190 +++++------------------------
 gcc/tree-flow-inline.h    | 172 +++++++++++++++++++++++++++
 gcc/tree-into-ssa.c       | 243 ++++----------------------------------
 gcc/tree-outof-ssa.c      |  33 ++----
 gcc/tree-pretty-print.c   |  25 ++--
 gcc/tree-sra.c            |  20 +---
 gcc/tree-ssa-alias.c      |  42 ++-----
 gcc/tree-ssa-ccp.c        |  91 ++++----------
 gcc/tree-ssa-dce.c        |  31 ++---
 gcc/tree-ssa-dom.c        |  65 ++--------
 gcc/tree-ssa-live.c       |  70 +++--------
 gcc/tree-ssa-loop-im.c    |  61 +++-------
 gcc/tree-ssa-loop-manip.c |  42 ++-----
 gcc/tree-ssa-operands.c   |   4 +
 gcc/tree-ssa-operands.h   |  74 ++++++++++++
 gcc/tree-ssa.c            |  73 +++---------
 gcc/tree-ssanames.c       |  22 +---
 gcc/tree-vectorizer.c     |  26 +---
 20 files changed, 509 insertions(+), 852 deletions(-)

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index c946ef69d869..7229f5a6e25f 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,60 @@
+2004-08-25  Andrew MacLeod  <amacleod@redhat.com>
+
+	* tree-ssa-operands.h (struct ssa_operand_iterator_d): New.  SSA operand
+	iterator controlling structure.
+	(SSA_OP_USE, SSA_OP_DEF, SSA_OP_VUSE, SSA_OP_VMAYUSE, SSA_OP_VMAYDEF,
+	SSA_OP_VMUSTDEF, SSA_OP_VIRTUAL_USES, SSA_OP_VIRTUAL_DEFS,
+	SSA_OP_ALL_USES, SSA_OP_ALL_DEFS, SSA_OP_ALL_OPERANDS): New.  Operand
+	iterator flags.
+	(FOR_EACH_SSA_TREE_OPERAND): New.  Iterate over operands as trees.
+	(FOR_EACH_SSA_USE_OPERAND): New.  Iterate over operands as uses.
+	(FOR_EACH_SSA_DEF_OPERAND): New.  Iterate over operands as defs.
+	(FOR_EACH_SSA_MAYDEF_OPERAND): New.  Iterate over V_MAY_DEFs.
+	* tree-ssa-operands.c (NULL_DEF_OPERAND_P, NULL_USE_OPERAND_P): New. 
+	Empty operand pointers.
+	* tree-flow-inline.h (op_iter_done): New.  Return true if finished.
+	(op_iter_next_use): New.  Return next use_operand_p.
+	(op_iter_next_def): New.  Return next def_operand_p.
+	(op_iter_next_tree): New.  Return next operands as a tree.
+	(op_iter_init): New.  Initialize an iterator structure.
+	(op_iter_init_use): New.  Initialize structure and get the first use.
+	(op_iter_init_def): New.  Initialize structure and get the first def.
+	(op_iter_init_tree): New.  Initialize structure and get the first tree.
+	(op_iter_next_maydef): New.  Return next V_MAY_DEF operands.
+	(op_iter_init_maydef): New.  Initialize structure and get the first 
+	V_MAY_DEF operands.
+	* tree-cfg.c (tree_duplicate_bb): Use new operand iterator.
+	* tree-dfa.c (compute_immediate_uses_for_stmt, 
+	redirect_immediate_uses): Use new operand iterator.
+	(v_may_defs_disappeared_p, v_must_defs_disappeared_p): Delete.
+	(mark_new_vars_to_rename): Use new operand iterator.  Count virtual
+	operands instead of using *_disappeared_p routines.
+	* tree-into-ssa.c (mark_def_sites, ssa_mark_def_sites, rewrite_stmt,
+	ssa_rewrite_stmt): Use new operand iterator.
+	* tree-outof-ssa.c (check_replaceable, find_replaceable_in_bb,
+	rewrite_trees): Use new operand iterator.
+	* tree-pretty-print.c (dump_vops): Use new operand iterator.
+	* tree-sra.c (mark_all_v_defs): Use new operand iterator.
+	* tree-ssa-alias.c (compute_points_to_and_addr_escape, 
+	dump_points_to_info): Use new operand iterator.
+	* tree-ssa-ccp.c (cp_lattice_meet, visit_stmt, initialize, 
+	replace_uses_in, replace_vuse_in, likely_value, set_rhs): Use new 
+	operand iterator.
+	* tree-ssa-dce.c (mark_stmt_if_obviously_necessary, 
+	propagate_necessity): Use new operand iterator.
+	* tree-ssa-dom.c (cprop_into_stmt, optimize_stmt): Use operand iterator.
+	(register_definitions_for_stmt): Use new operand iterator.  Take stmt as
+	a parameter instead of a stmt_ann_t.
+	* tree-ssa-live.c (create_ssa_var_map, calculate_live_on_entry,
+	build_tree_conflict_graph): Use new operand iterator.
+	* tree-ssa-loop-im.c (determine_max_movement, single_reachable_address,
+	rewrite_mem_refs): Use new operand iterator.
+	* tree-ssa-loop-manip.c (find_uses_to_rename_stmt, 
+	check_loop_closed_ssa_use): Use new operand iterator.
+	* tree-ssa.c (verify_ssa, replace_immediate_uses): Use operand iterator.
+	* tree-ssanames.c (release_defs): Use new operand iterator.
+	* tree-vectorizer.c (vect_create_data_ref): Use new operand iterator.
+
 2004-08-25  Adam Nemet  <anemet@lnxw.com>
 
 	* tlink.c (initial_cwd): New variable.
diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c
index dce8e4152d10..dab912550d61 100644
--- a/gcc/tree-cfg.c
+++ b/gcc/tree-cfg.c
@@ -4245,11 +4245,8 @@ tree_duplicate_bb (basic_block bb)
 {
   basic_block new_bb;
   block_stmt_iterator bsi, bsi_tgt;
-  tree phi;
-  def_optype defs;
-  v_may_def_optype v_may_defs;
-  v_must_def_optype v_must_defs;
-  unsigned j;
+  tree phi, val;
+  ssa_op_iter op_iter;
 
   new_bb = create_empty_bb (EXIT_BLOCK_PTR->prev_bb);
 
@@ -4270,17 +4267,8 @@ tree_duplicate_bb (basic_block bb)
       /* Record the definitions.  */
       get_stmt_operands (stmt);
 
-      defs = STMT_DEF_OPS (stmt);
-      for (j = 0; j < NUM_DEFS (defs); j++)
-	mark_for_rewrite (DEF_OP (defs, j));
-
-      v_may_defs = STMT_V_MAY_DEF_OPS (stmt);
-      for (j = 0; j < NUM_V_MAY_DEFS (v_may_defs); j++)
-	mark_for_rewrite (V_MAY_DEF_RESULT (v_may_defs, j));
-
-      v_must_defs = STMT_V_MUST_DEF_OPS (stmt);
-      for (j = 0; j < NUM_V_MUST_DEFS (v_must_defs); j++)
-	mark_for_rewrite (V_MUST_DEF_OP (v_must_defs, j));
+      FOR_EACH_SSA_TREE_OPERAND (val, stmt, op_iter, SSA_OP_ALL_DEFS)
+	mark_for_rewrite (val);
 
       copy = unshare_expr (stmt);
 
diff --git a/gcc/tree-dfa.c b/gcc/tree-dfa.c
index b8a9b03324f7..8e7dec5825ca 100644
--- a/gcc/tree-dfa.c
+++ b/gcc/tree-dfa.c
@@ -270,11 +270,8 @@ compute_immediate_uses_for_phi (tree phi, bool (*calc_for)(tree))
 static void
 compute_immediate_uses_for_stmt (tree stmt, int flags, bool (*calc_for)(tree))
 {
-  size_t i;
-  use_optype uses;
-  vuse_optype vuses;
-  v_may_def_optype v_may_defs;
-  stmt_ann_t ann;
+  tree use;
+  ssa_op_iter iter;
 
 #ifdef ENABLE_CHECKING
   /* PHI nodes are handled elsewhere.  */
@@ -283,13 +280,10 @@ compute_immediate_uses_for_stmt (tree stmt, int flags, bool (*calc_for)(tree))
 #endif
 
   /* Look at USE_OPS or VUSE_OPS according to FLAGS.  */
-  ann = stmt_ann (stmt);
   if (flags & TDFA_USE_OPS)
     {
-      uses = USE_OPS (ann);
-      for (i = 0; i < NUM_USES (uses); i++)
+      FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_USE)
 	{
-	  tree use = USE_OP (uses, i);
 	  tree imm_stmt = SSA_NAME_DEF_STMT (use);
 	  if (!IS_EMPTY_STMT (imm_stmt) && (!calc_for || calc_for (use)))
 	    add_immediate_use (imm_stmt, stmt);
@@ -298,21 +292,10 @@ compute_immediate_uses_for_stmt (tree stmt, int flags, bool (*calc_for)(tree))
 
   if (flags & TDFA_USE_VOPS)
     {
-      vuses = VUSE_OPS (ann);
-      for (i = 0; i < NUM_VUSES (vuses); i++)
+      FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_VIRTUAL_USES)
 	{
-	  tree vuse = VUSE_OP (vuses, 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);
-	}
-
-      v_may_defs = V_MAY_DEF_OPS (ann);
-      for (i = 0; i < NUM_V_MAY_DEFS (v_may_defs); 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)))
+	  tree imm_rdef_stmt = SSA_NAME_DEF_STMT (use);
+	  if (!IS_EMPTY_STMT (imm_rdef_stmt) && (!calc_for || calc_for (use)))
 	    add_immediate_use (imm_rdef_stmt, stmt);
 	}
     }
@@ -380,21 +363,11 @@ redirect_immediate_use (tree use, tree old, tree new)
 void
 redirect_immediate_uses (tree old, tree new)
 {
-  stmt_ann_t ann = get_stmt_ann (old);
-  use_optype uses = USE_OPS (ann);
-  vuse_optype vuses = VUSE_OPS (ann);
-  v_may_def_optype v_may_defs = V_MAY_DEF_OPS (ann);
-  unsigned int i;
+  ssa_op_iter iter;
+  tree val;
 
-  /* Look at USE_OPS or VUSE_OPS according to FLAGS.  */
-  for (i = 0; i < NUM_USES (uses); i++)
-    redirect_immediate_use (USE_OP (uses, i), old, new);
-
-  for (i = 0; i < NUM_VUSES (vuses); i++)
-    redirect_immediate_use (VUSE_OP (vuses, 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);
+  FOR_EACH_SSA_TREE_OPERAND (val, old, iter, SSA_OP_ALL_USES)
+    redirect_immediate_use (val, old, new);
 }
 
 
@@ -956,48 +929,6 @@ 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 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
-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 (v_must_defs_before == NULL)
-    return false;
-
-  /* All/some of them gone.  */
-  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;
-}
-
 
 /* Add all the non-SSA variables found in STMT's operands to the bitmap
    VARS_TO_RENAME.  */
@@ -1005,17 +936,12 @@ v_must_defs_disappeared_p (v_must_def_optype v_must_defs_before,
 void
 mark_new_vars_to_rename (tree stmt, bitmap vars_to_rename)
 {
-  def_optype defs;
-  use_optype uses;
-  v_may_def_optype v_may_defs;
-  vuse_optype vuses;
-  v_must_def_optype v_must_defs;
-  size_t i;
+  ssa_op_iter iter;
+  tree val;
   bitmap vars_in_vops_to_rename;
   bool found_exposed_symbol = false;
-  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;
+  int v_may_defs_before, v_may_defs_after;
+  int v_must_defs_before, v_must_defs_after;
 
   vars_in_vops_to_rename = BITMAP_XMALLOC ();
 
@@ -1028,32 +954,15 @@ mark_new_vars_to_rename (tree stmt, bitmap vars_to_rename)
      We flag them in a separate bitmap because we don't really want to
      rename them if there are not any newly exposed symbols in the
      statement operands.  */
-  ann = stmt_ann (stmt);
-  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 = 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);
-    }
+  v_may_defs_before = NUM_V_MAY_DEFS (STMT_V_MAY_DEF_OPS (stmt));
+  v_must_defs_before = NUM_V_MUST_DEFS (STMT_V_MUST_DEF_OPS (stmt));
 
-  vuses = VUSE_OPS (ann);
-  for (i = 0; i < NUM_VUSES (vuses); i++)
+  FOR_EACH_SSA_TREE_OPERAND (val, stmt, iter, 
+			     SSA_OP_VMAYDEF | SSA_OP_VUSE | SSA_OP_VMUSTDEF)
     {
-      tree var = VUSE_OP (vuses, i);
-      if (!DECL_P (var))
-	var = SSA_NAME_VAR (var);
-      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);
+      if (!DECL_P (val))
+	val = SSA_NAME_VAR (val);
+      bitmap_set_bit (vars_in_vops_to_rename, var_ann (val)->uid);
     }
 
   /* Now force an operand re-scan on the statement and mark any newly
@@ -1061,58 +970,17 @@ mark_new_vars_to_rename (tree stmt, bitmap vars_to_rename)
   modify_stmt (stmt);
   get_stmt_operands (stmt);
 
-  defs = DEF_OPS (ann);
-  for (i = 0; i < NUM_DEFS (defs); i++)
-    {
-      tree var = DEF_OP (defs, i);
-      if (DECL_P (var))
-	{
-	  found_exposed_symbol = true;
-	  bitmap_set_bit (vars_to_rename, var_ann (var)->uid);
-	}
-    }
+  v_may_defs_after = NUM_V_MAY_DEFS (STMT_V_MAY_DEF_OPS (stmt));
+  v_must_defs_after = NUM_V_MUST_DEFS (STMT_V_MUST_DEF_OPS (stmt));
 
-  uses = USE_OPS (ann);
-  for (i = 0; i < NUM_USES (uses); i++)
-    {
-      tree var = USE_OP (uses, i);
-      if (DECL_P (var))
-	{
-	  found_exposed_symbol = true;
-	  bitmap_set_bit (vars_to_rename, var_ann (var)->uid);
-	}
-    }
-
-  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 = V_MAY_DEF_RESULT (v_may_defs, i);
-      if (DECL_P (var))
-	{
-	  found_exposed_symbol = true;
-	  bitmap_set_bit (vars_to_rename, var_ann (var)->uid);
-	}
-    }
-
-  vuses = VUSE_OPS (ann);
-  for (i = 0; i < NUM_VUSES (vuses); i++)
-    {
-      tree var = VUSE_OP (vuses, i);
-      if (DECL_P (var))
-	{
-	  found_exposed_symbol = true;
-	  bitmap_set_bit (vars_to_rename, var_ann (var)->uid);
-	}
-    }
+  FOR_EACH_SSA_TREE_OPERAND (val, stmt, iter, 
+			     SSA_OP_VMAYDEF | SSA_OP_VUSE | SSA_OP_VMUSTDEF)
 
-  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))
+      if (DECL_P (val))
 	{
 	  found_exposed_symbol = true;
-	  bitmap_set_bit (vars_to_rename, var_ann (var)->uid);
+	  bitmap_set_bit (vars_to_rename, var_ann (val)->uid);
 	}
     }
 
@@ -1122,8 +990,8 @@ mark_new_vars_to_rename (tree stmt, bitmap vars_to_rename)
      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
-      || 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))
+      || v_may_defs_before > v_may_defs_after
+      || 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);
diff --git a/gcc/tree-flow-inline.h b/gcc/tree-flow-inline.h
index a9cc21325e8c..423088c9e51f 100644
--- a/gcc/tree-flow-inline.h
+++ b/gcc/tree-flow-inline.h
@@ -673,4 +673,176 @@ get_tree_ann (tree t)
   return (ann) ? ann : create_tree_ann (t);
 }
 
+/*  -----------------------------------------------------------------------  */
+
+/* The following set of routines are used to iterator over various type of
+   SSA operands.  */
+
+/* Return true if PTR is finished iterating.  */
+static inline bool
+op_iter_done (ssa_op_iter *ptr)
+{
+  return ptr->done;
+}
+
+/* Get the next iterator use value for PTR.  */
+static inline use_operand_p
+op_iter_next_use (ssa_op_iter *ptr)
+{
+  if (ptr->use_i < ptr->num_use)
+    {
+      return USE_OP_PTR (ptr->ops->use_ops, (ptr->use_i)++);
+    }
+  if (ptr->vuse_i < ptr->num_vuse)
+    {
+      return VUSE_OP_PTR (ptr->ops->vuse_ops, (ptr->vuse_i)++);
+    }
+  if (ptr->v_mayu_i < ptr->num_v_mayu)
+    {
+      return V_MAY_DEF_OP_PTR (ptr->ops->v_may_def_ops,
+				       (ptr->v_mayu_i)++);
+    }
+  ptr->done = true;
+  return NULL_USE_OPERAND_P;
+}
+
+/* Get the next iterator def value for PTR.  */
+static inline def_operand_p
+op_iter_next_def (ssa_op_iter *ptr)
+{
+  if (ptr->def_i < ptr->num_def)
+    {
+      return DEF_OP_PTR (ptr->ops->def_ops, (ptr->def_i)++);
+    }
+  if (ptr->v_must_i < ptr->num_v_must)
+    {
+      return V_MUST_DEF_OP_PTR (ptr->ops->v_must_def_ops, 
+					(ptr->v_must_i)++);
+    }
+  if (ptr->v_mayd_i < ptr->num_v_mayd)
+    {
+      return V_MAY_DEF_RESULT_PTR (ptr->ops->v_may_def_ops,
+					   (ptr->v_mayd_i)++);
+    }
+  ptr->done = true;
+  return NULL_DEF_OPERAND_P;
+}
+
+/* Get the next iterator tree value for PTR.  */
+static inline tree
+op_iter_next_tree (ssa_op_iter *ptr)
+{
+  if (ptr->use_i < ptr->num_use)
+    {
+      return USE_OP (ptr->ops->use_ops, (ptr->use_i)++);
+    }
+  if (ptr->vuse_i < ptr->num_vuse)
+    {
+      return VUSE_OP (ptr->ops->vuse_ops, (ptr->vuse_i)++);
+    }
+  if (ptr->v_mayu_i < ptr->num_v_mayu)
+    {
+      return V_MAY_DEF_OP (ptr->ops->v_may_def_ops, (ptr->v_mayu_i)++);
+    }
+  if (ptr->def_i < ptr->num_def)
+    {
+      return DEF_OP (ptr->ops->def_ops, (ptr->def_i)++);
+    }
+  if (ptr->v_must_i < ptr->num_v_must)
+    {
+      return V_MUST_DEF_OP (ptr->ops->v_must_def_ops, 
+					(ptr->v_must_i)++);
+    }
+  if (ptr->v_mayd_i < ptr->num_v_mayd)
+    {
+      return V_MAY_DEF_RESULT (ptr->ops->v_may_def_ops,
+					   (ptr->v_mayd_i)++);
+    }
+  ptr->done = true;
+  return NULL;
+}
+
+/* Initialize the iterator PTR to the virtual defs in STMT.  */
+static inline void
+op_iter_init (ssa_op_iter *ptr, tree stmt, int flags)
+{
+  stmt_operands_p ops;
+  stmt_ann_t ann = get_stmt_ann (stmt);
+
+  ops = &(ann->operands);
+  ptr->done = false;
+  ptr->ops = ops;
+  ptr->num_def = (flags & SSA_OP_DEF) ? NUM_DEFS (ops->def_ops) : 0;
+  ptr->num_use = (flags & SSA_OP_USE) ? NUM_USES (ops->use_ops) : 0;
+  ptr->num_vuse = (flags & SSA_OP_VUSE) ? NUM_VUSES (ops->vuse_ops) : 0;
+  ptr->num_v_mayu = (flags & SSA_OP_VMAYUSE)
+		     ?  NUM_V_MAY_DEFS (ops->v_may_def_ops) : 0;
+  ptr->num_v_mayd = (flags & SSA_OP_VMAYDEF) 
+		     ?  NUM_V_MAY_DEFS (ops->v_may_def_ops) : 0;
+  ptr->num_v_must = (flags & SSA_OP_VMUSTDEF) 
+		     ? NUM_V_MUST_DEFS (ops->v_must_def_ops) : 0;
+  ptr->def_i = 0;
+  ptr->use_i = 0;
+  ptr->vuse_i = 0;
+  ptr->v_mayu_i = 0;
+  ptr->v_mayd_i = 0;
+  ptr->v_must_i = 0;
+}
+
+/* Initialize iterator PTR to the use operands in STMT based on FLAGS. Return
+   the first use.  */
+static inline use_operand_p
+op_iter_init_use (ssa_op_iter *ptr, tree stmt, int flags)
+{
+  op_iter_init (ptr, stmt, flags);
+  return op_iter_next_use (ptr);
+}
+
+/* Initialize iterator PTR to the def operands in STMT based on FLAGS. Return
+   the first def.  */
+static inline def_operand_p
+op_iter_init_def (ssa_op_iter *ptr, tree stmt, int flags)
+{
+  op_iter_init (ptr, stmt, flags);
+  return op_iter_next_def (ptr);
+}
+
+/* Initialize iterator PTR to the operands in STMT based on FLAGS. Return
+   the first operand as a tree.  */
+static inline tree
+op_iter_init_tree (ssa_op_iter *ptr, tree stmt, int flags)
+{
+  op_iter_init (ptr, stmt, flags);
+  return op_iter_next_tree (ptr);
+}
+
+/* Get the next iterator maydef value for PTR, returning the maydef values in
+   USE and DEF.  */
+static inline void
+op_iter_next_maydef (use_operand_p *use, def_operand_p *def, ssa_op_iter *ptr)
+{
+  if (ptr->v_mayu_i < ptr->num_v_mayu)
+    {
+      *def = V_MAY_DEF_RESULT_PTR (ptr->ops->v_may_def_ops, ptr->v_mayu_i);
+      *use = V_MAY_DEF_OP_PTR (ptr->ops->v_may_def_ops, (ptr->v_mayu_i)++);
+      return;
+    }
+  else
+    {
+      *def = NULL_DEF_OPERAND_P;
+      *use = NULL_USE_OPERAND_P;
+    }
+  ptr->done = true;
+  return;
+}
+
+/* Initialize iterator PTR to the operands in STMT.  Return the first operands
+   in USE and DEF.  */
+static inline void
+op_iter_init_maydef (ssa_op_iter *ptr, tree stmt, use_operand_p *use, 
+		     def_operand_p *def)
+{
+  op_iter_init (ptr, stmt, SSA_OP_VMAYUSE);
+  op_iter_next_maydef (use, def, ptr);
+}
 #endif /* _TREE_FLOW_INLINE_H  */
diff --git a/gcc/tree-into-ssa.c b/gcc/tree-into-ssa.c
index edeeab5f1bf9..6387b7fadd56 100644
--- a/gcc/tree-into-ssa.c
+++ b/gcc/tree-into-ssa.c
@@ -342,71 +342,50 @@ mark_def_sites (struct dom_walk_data *walk_data,
 {
   struct mark_def_sites_global_data *gd = walk_data->global_data;
   sbitmap kills = gd->kills;
-  v_may_def_optype v_may_defs;
-  v_must_def_optype v_must_defs;
-  vuse_optype vuses;
-  def_optype defs;
-  use_optype uses;
-  size_t i, uid;
-  tree stmt;
-  stmt_ann_t ann;
+  size_t uid;
+  tree stmt, def;
+  use_operand_p use_p;
+  def_operand_p def_p;
+  ssa_op_iter iter;
 
   /* Mark all the blocks that have definitions for each variable in the
      VARS_TO_RENAME bitmap.  */
   stmt = bsi_stmt (bsi);
   get_stmt_operands (stmt);
-  ann = stmt_ann (stmt);
 
   /* If a variable is used before being set, then the variable is live
      across a block boundary, so mark it live-on-entry to BB.  */
-  uses = USE_OPS (ann);
-  for (i = 0; i < NUM_USES (uses); i++)
-    {
-      use_operand_p use_p = USE_OP_PTR (uses, i);
 
-      if (prepare_use_operand_for_rename (use_p, &uid)
-	  && !TEST_BIT (kills, uid))
-	set_livein_block (USE_FROM_PTR (use_p), bb);
-    }
-	  
-  /* Similarly for virtual uses.  */
-  vuses = VUSE_OPS (ann);
-  for (i = 0; i < NUM_VUSES (vuses); i++)
+  FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_USE | SSA_OP_VUSE)
     {
-      use_operand_p use_p = VUSE_OP_PTR (vuses, i);
-
       if (prepare_use_operand_for_rename (use_p, &uid)
 	  && !TEST_BIT (kills, uid))
 	set_livein_block (USE_FROM_PTR (use_p), bb);
     }
-
+	  
   /* Note that virtual definitions are irrelevant for computing KILLS
      because a V_MAY_DEF does not constitute a killing definition of the
      variable.  However, the operand of a virtual definitions is a use
      of the variable, so it may cause the variable to be considered
      live-on-entry.  */
-  v_may_defs = V_MAY_DEF_OPS (ann);
-  for (i = 0; i < NUM_V_MAY_DEFS (v_may_defs); i++)
+
+  FOR_EACH_SSA_MAYDEF_OPERAND (def_p, use_p, stmt, iter)
     {
-      use_operand_p use_p = V_MAY_DEF_OP_PTR (v_may_defs, i);
       if (prepare_use_operand_for_rename (use_p, &uid))
 	{
 	  /* If we do not already have an SSA_NAME for our destination,
 	     then set the destination to the source.  */
-	  if (TREE_CODE (V_MAY_DEF_RESULT (v_may_defs, i)) != SSA_NAME)
-	    SET_V_MAY_DEF_RESULT (v_may_defs, i, USE_FROM_PTR (use_p));
+	  if (TREE_CODE (DEF_FROM_PTR (def_p)) != SSA_NAME)
+	    SET_DEF (def_p, USE_FROM_PTR (use_p));
 	    
           set_livein_block (USE_FROM_PTR (use_p), bb);
-	  set_def_block (V_MAY_DEF_RESULT (v_may_defs, i), bb, false, false);
+	  set_def_block (DEF_FROM_PTR (def_p), bb, false, false);
 	}
     }
 
   /* 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++)
+  FOR_EACH_SSA_TREE_OPERAND (def, stmt, iter, SSA_OP_DEF | SSA_OP_VMUSTDEF)
     {
-      tree def = V_MUST_DEF_OP (v_must_defs, i);
-
       if (prepare_def_operand_for_rename (def, &uid))
 	{
 	  set_def_block (def, bb, false, false);
@@ -414,19 +393,6 @@ mark_def_sites (struct dom_walk_data *walk_data,
 	}
     }
 
-  /* Now process the definition made by this statement.  Mark the
-     variables in KILLS.  */
-  defs = DEF_OPS (ann);
-  for (i = 0; i < NUM_DEFS (defs); i++)
-    {
-      tree def = DEF_OP (defs, i);
-
-      if (prepare_def_operand_for_rename (def, &uid))
-	{
-	  set_def_block (def, bb, false, false);
-	  SET_BIT (kills, uid);
-	}
-    }
 }
 
 /* Ditto, but works over ssa names.  */
@@ -438,27 +404,19 @@ ssa_mark_def_sites (struct dom_walk_data *walk_data,
 {
   struct mark_def_sites_global_data *gd = walk_data->global_data;
   sbitmap kills = gd->kills;
-  v_may_def_optype v_may_defs;
-  v_must_def_optype v_must_defs;
-  vuse_optype vuses;
-  def_optype defs;
-  use_optype uses;
-  size_t i, uid, def_uid;
+  size_t uid, def_uid;
   tree stmt, use, def;
-  stmt_ann_t ann;
+  ssa_op_iter iter;
 
   /* Mark all the blocks that have definitions for each variable in the
      names_to_rename bitmap.  */
   stmt = bsi_stmt (bsi);
   get_stmt_operands (stmt);
-  ann = stmt_ann (stmt);
 
   /* If a variable is used before being set, then the variable is live
      across a block boundary, so mark it live-on-entry to BB.  */
-  uses = USE_OPS (ann);
-  for (i = 0; i < NUM_USES (uses); i++)
+  FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_ALL_USES)
     {
-      use = USE_OP (uses, i);
       uid = SSA_NAME_VERSION (use);
 
       if (TEST_BIT (gd->names_to_rename, uid)
@@ -466,61 +424,10 @@ ssa_mark_def_sites (struct dom_walk_data *walk_data,
 	set_livein_block (use, bb);
     }
 	  
-  /* Similarly for virtual uses.  */
-  vuses = VUSE_OPS (ann);
-  for (i = 0; i < NUM_VUSES (vuses); i++)
-    {
-      use = VUSE_OP (vuses, i);
-      uid = SSA_NAME_VERSION (use);
-
-      if (TEST_BIT (gd->names_to_rename, uid)
-	  && !TEST_BIT (kills, uid))
-	set_livein_block (use, bb);
-    }
-
-  v_may_defs = V_MAY_DEF_OPS (ann);
-  for (i = 0; i < NUM_V_MAY_DEFS (v_may_defs); i++)
-    {
-      use = V_MAY_DEF_OP (v_may_defs, i);
-      uid = SSA_NAME_VERSION (use);
-
-      if (TEST_BIT (gd->names_to_rename, uid)
-	  && !TEST_BIT (kills, uid))
-	set_livein_block (use, bb);
-    }
-
   /* Now process the definition made by this statement.  Mark the
      variables in KILLS.  */
-  defs = DEF_OPS (ann);
-  for (i = 0; i < NUM_DEFS (defs); i++)
-    {
-      def = DEF_OP (defs, i);
-      def_uid = SSA_NAME_VERSION (def);
-
-      if (TEST_BIT (gd->names_to_rename, def_uid))
-	{
-	  set_def_block (def, bb, false, true);
-	  SET_BIT (kills, def_uid);
-	}
-    }
-
-  v_may_defs = V_MAY_DEF_OPS (ann);
-  for (i = 0; i < NUM_V_MAY_DEFS (v_may_defs); i++)
-    {
-      def = V_MAY_DEF_RESULT (v_may_defs, i);
-      def_uid = SSA_NAME_VERSION (def);
-
-      if (TEST_BIT (gd->names_to_rename, def_uid))
-	{
-	  set_def_block (def, bb, false, true);
-	  SET_BIT (kills, def_uid);
-	}
-    }
-
-  v_must_defs = V_MUST_DEF_OPS (ann);
-  for (i = 0; i < NUM_V_MUST_DEFS (v_must_defs); i++)
+  FOR_EACH_SSA_TREE_OPERAND (def, stmt, iter, SSA_OP_ALL_DEFS)
     {
-      def = V_MUST_DEF_OP (v_must_defs, i);
       def_uid = SSA_NAME_VERSION (def);
 
       if (TEST_BIT (gd->names_to_rename, def_uid))
@@ -1138,14 +1045,11 @@ rewrite_stmt (struct dom_walk_data *walk_data,
 	      basic_block bb ATTRIBUTE_UNUSED,
 	      block_stmt_iterator si)
 {
-  size_t i;
   stmt_ann_t ann;
   tree stmt;
-  vuse_optype vuses;
-  v_may_def_optype v_may_defs;
-  v_must_def_optype v_must_defs;
-  def_optype defs;
-  use_optype uses;
+  use_operand_p use_p;
+  def_operand_p def_p;
+  ssa_op_iter iter;
   struct rewrite_block_data *bd;
 
   bd = VARRAY_TOP_GENERIC_PTR (walk_data->block_data_stack);
@@ -1167,25 +1071,13 @@ rewrite_stmt (struct dom_walk_data *walk_data,
     abort ();
 #endif
 
-  defs = DEF_OPS (ann);
-  uses = USE_OPS (ann);
-  vuses = VUSE_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++)
-    rewrite_operand (USE_OP_PTR (uses, i));
-
-  /* Rewrite virtual uses in the statement.  */
-  for (i = 0; i < NUM_VUSES (vuses); i++)
-    rewrite_operand (VUSE_OP_PTR (vuses, i));
+  FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_ALL_USES)
+    rewrite_operand (use_p);
 
   /* Step 2.  Register the statement's DEF and VDEF operands.  */
-  for (i = 0; i < NUM_DEFS (defs); i++)
+  FOR_EACH_SSA_DEF_OPERAND (def_p, stmt, iter, SSA_OP_ALL_DEFS)
     {
-      def_operand_p def_p = DEF_OP_PTR (defs, i);
-
       if (TREE_CODE (DEF_FROM_PTR (def_p)) != SSA_NAME)
 	SET_DEF (def_p, make_ssa_name (DEF_FROM_PTR (def_p), stmt));
 
@@ -1193,36 +1085,6 @@ rewrite_stmt (struct dom_walk_data *walk_data,
 	 doesn't need to be renamed.  */
       register_new_def (DEF_FROM_PTR (def_p), &bd->block_defs);
     }
-
-  /* Register new virtual definitions made by the statement.  */
-  for (i = 0; i < NUM_V_MAY_DEFS (v_may_defs); i++)
-    {
-      rewrite_operand (V_MAY_DEF_OP_PTR (v_may_defs, i));
-
-      if (TREE_CODE (V_MAY_DEF_RESULT (v_may_defs, i)) != SSA_NAME)
-	SET_V_MAY_DEF_RESULT (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 (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++)
-    {
-      def_operand_p v_must_def_p = V_MUST_DEF_OP_PTR (v_must_defs, i);
-
-      if (TREE_CODE (DEF_FROM_PTR (v_must_def_p)) != SSA_NAME)
-	SET_DEF (v_must_def_p, 
-		 make_ssa_name (DEF_FROM_PTR (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 (DEF_FROM_PTR (v_must_def_p), &bd->block_defs);
-    }
-    
 }
 
 /* Ditto, for rewriting ssa names.  */
@@ -1232,16 +1094,11 @@ ssa_rewrite_stmt (struct dom_walk_data *walk_data,
 		  basic_block bb ATTRIBUTE_UNUSED,
 		  block_stmt_iterator si)
 {
-  size_t i;
   stmt_ann_t ann;
   tree stmt, var;
+  ssa_op_iter iter;
   use_operand_p use_p;
   def_operand_p def_p;
-  vuse_optype vuses;
-  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;
   sbitmap names_to_rename = walk_data->global_data;
 
@@ -1264,64 +1121,16 @@ ssa_rewrite_stmt (struct dom_walk_data *walk_data,
     abort ();
 #endif
 
-  defs = DEF_OPS (ann);
-  uses = USE_OPS (ann);
-  vuses = VUSE_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++)
+  FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_ALL_USES)
     {
-      use_p = USE_OP_PTR (uses, i);
-      if (TEST_BIT (names_to_rename, SSA_NAME_VERSION (USE_FROM_PTR (use_p))))
-	SET_USE (use_p, get_reaching_def (USE_FROM_PTR (use_p)));
-    }
-
-  /* Rewrite virtual uses in the statement.  */
-  for (i = 0; i < NUM_VUSES (vuses); i++)
-    {
-      use_p = VUSE_OP_PTR (vuses, i);
-      if (TEST_BIT (names_to_rename, SSA_NAME_VERSION (USE_FROM_PTR (use_p))))
-	SET_USE (use_p, get_reaching_def (USE_FROM_PTR (use_p)));
-    }
-
-  for (i = 0; i < NUM_V_MAY_DEFS (v_may_defs); i++)
-    {
-      use_p = V_MAY_DEF_OP_PTR (v_may_defs, i);
       if (TEST_BIT (names_to_rename, SSA_NAME_VERSION (USE_FROM_PTR (use_p))))
 	SET_USE (use_p, get_reaching_def (USE_FROM_PTR (use_p)));
     }
 
   /* Step 2.  Register the statement's DEF and VDEF operands.  */
-  for (i = 0; i < NUM_DEFS (defs); i++)
-    {
-      def_p = DEF_OP_PTR (defs, i);
-      var = DEF_FROM_PTR (def_p);
-
-      if (!TEST_BIT (names_to_rename, SSA_NAME_VERSION (var)))
-	continue;
-
-      SET_DEF (def_p, duplicate_ssa_name (var, stmt));
-      ssa_register_new_def (var, DEF_FROM_PTR (def_p), &bd->block_defs);
-    }
-
-  /* Register new virtual definitions made by the statement.  */
-  for (i = 0; i < NUM_V_MAY_DEFS (v_may_defs); i++)
-    {
-      def_p = V_MAY_DEF_RESULT_PTR (v_may_defs, i);
-      var = DEF_FROM_PTR (def_p);
-
-      if (!TEST_BIT (names_to_rename, SSA_NAME_VERSION (var)))
-	continue;
-
-      SET_DEF (def_p, duplicate_ssa_name (var, stmt));
-      ssa_register_new_def (var, DEF_FROM_PTR (def_p), &bd->block_defs);
-    }
-
-  for (i = 0; i < NUM_V_MUST_DEFS (v_must_defs); i++)
+  FOR_EACH_SSA_DEF_OPERAND (def_p, stmt, iter, SSA_OP_ALL_DEFS)
     {
-      def_p = V_MUST_DEF_OP_PTR (v_must_defs, i);
       var = DEF_FROM_PTR (def_p);
 
       if (!TEST_BIT (names_to_rename, SSA_NAME_VERSION (var)))
diff --git a/gcc/tree-outof-ssa.c b/gcc/tree-outof-ssa.c
index 5b1e2a8fc1e4..0245494690ae 100644
--- a/gcc/tree-outof-ssa.c
+++ b/gcc/tree-outof-ssa.c
@@ -1461,8 +1461,9 @@ check_replaceable (temp_expr_table_p tab, tree stmt)
   def_optype defs;
   use_optype uses;
   tree var, def;
-  int num_use_ops, version, i;
+  int num_use_ops, version;
   var_map map = tab->map;
+  ssa_op_iter iter;
 
   if (TREE_CODE (stmt) != MODIFY_EXPR)
     return false;
@@ -1512,9 +1513,8 @@ check_replaceable (temp_expr_table_p tab, tree stmt)
   version = SSA_NAME_VERSION (def);
 
   /* Add this expression to the dependency list for each use partition.  */
-  for (i = 0; i < num_use_ops; i++)
+  FOR_EACH_SSA_TREE_OPERAND (var, stmt, iter, SSA_OP_USE)
     {
-      var = USE_OP (uses, i);
       add_dependance (tab, version, var);
     }
 
@@ -1646,11 +1646,10 @@ find_replaceable_in_bb (temp_expr_table_p tab, basic_block bb)
   block_stmt_iterator bsi;
   tree stmt, def;
   stmt_ann_t ann;
-  int partition, num, i;
-  use_optype uses;
-  def_optype defs;
+  int partition;
   var_map map = tab->map;
   value_expr_p p;
+  ssa_op_iter iter;
 
   for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
     {
@@ -1658,11 +1657,8 @@ find_replaceable_in_bb (temp_expr_table_p tab, basic_block bb)
       ann = stmt_ann (stmt);
 
       /* Determine if this stmt finishes an existing expression.  */
-      uses = USE_OPS (ann);
-      num = NUM_USES (uses);
-      for (i = 0; i < num; i++)
+      FOR_EACH_SSA_TREE_OPERAND (def, stmt, iter, SSA_OP_USE)
 	{
-	  def = USE_OP (uses, i);
 	  if (tab->version_info[SSA_NAME_VERSION (def)])
 	    {
 	      /* Mark expression as replaceable unless stmt is volatile.  */
@@ -1674,11 +1670,8 @@ find_replaceable_in_bb (temp_expr_table_p tab, basic_block bb)
 	}
       
       /* Next, see if this stmt kills off an active expression.  */
-      defs = DEF_OPS (ann);
-      num = NUM_DEFS (defs);
-      for (i = 0; i < num; i++)
+      FOR_EACH_SSA_TREE_OPERAND (def, stmt, iter, SSA_OP_DEF)
 	{
-	  def = DEF_OP (defs, i);
 	  partition = var_to_partition (map, def);
 	  if (partition != NO_PARTITION && tab->partition_dep_list[partition])
 	    kill_expr (tab, partition, true);
@@ -1880,13 +1873,15 @@ rewrite_trees (var_map map, tree *values)
     {
       for (si = bsi_start (bb); !bsi_end_p (si); )
 	{
-	  size_t i, num_uses, num_defs;
+	  size_t num_uses, num_defs;
 	  use_optype uses;
 	  def_optype defs;
 	  tree stmt = bsi_stmt (si);
 	  use_operand_p use_p;
+	  def_operand_p def_p;
 	  int remove = 0, is_copy = 0;
 	  stmt_ann_t ann;
+	  ssa_op_iter iter;
 
 	  get_stmt_operands (stmt);
 	  ann = stmt_ann (stmt);
@@ -1898,10 +1893,8 @@ rewrite_trees (var_map map, tree *values)
 
 	  uses = USE_OPS (ann);
 	  num_uses = NUM_USES (uses);
-
-	  for (i = 0; i < num_uses; i++)
+	  FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_USE)
 	    {
-	      use_p = USE_OP_PTR (uses, i);
 	      if (replace_use_variable (map, use_p, values))
 	        changed = true;
 	    }
@@ -1921,10 +1914,8 @@ rewrite_trees (var_map map, tree *values)
 	    }
 	  if (!remove)
 	    {
-	      for (i = 0; i < num_defs; i++)
+	      FOR_EACH_SSA_DEF_OPERAND (def_p, stmt, iter, SSA_OP_DEF)
 		{
-		  def_operand_p def_p = DEF_OP_PTR (defs, i);
-
 		  if (replace_def_variable (map, def_p, NULL))
 		    changed = true;
 
diff --git a/gcc/tree-pretty-print.c b/gcc/tree-pretty-print.c
index a00d7178a6ab..1cc5e7494c34 100644
--- a/gcc/tree-pretty-print.c
+++ b/gcc/tree-pretty-print.c
@@ -2036,38 +2036,35 @@ newline_and_indent (pretty_printer *buffer, int spc)
 static void
 dump_vops (pretty_printer *buffer, tree stmt, int spc, int flags)
 {
-  size_t i;
-  stmt_ann_t ann = stmt_ann (stmt);
-  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);
+  tree use, def;
+  use_operand_p use_p;
+  def_operand_p def_p;
+  ssa_op_iter iter;
 
-  for (i = 0; i < NUM_V_MAY_DEFS (v_may_defs); i++)
+  FOR_EACH_SSA_MAYDEF_OPERAND (def_p, use_p, stmt, iter)
     {
       pp_string (buffer, "#   ");
-      dump_generic_node (buffer, V_MAY_DEF_RESULT (v_may_defs, i),
+      dump_generic_node (buffer, DEF_FROM_PTR (def_p),
                          spc + 2, flags, false);
       pp_string (buffer, " = V_MAY_DEF <");
-      dump_generic_node (buffer, V_MAY_DEF_OP (v_may_defs, i),
+      dump_generic_node (buffer, USE_FROM_PTR (use_p),
                          spc + 2, flags, false);
       pp_string (buffer, ">;");
       newline_and_indent (buffer, spc);
     }
 
-  for (i = 0; i < NUM_V_MUST_DEFS (v_must_defs); i++)
+  FOR_EACH_SSA_TREE_OPERAND (def, stmt, iter, SSA_OP_VMUSTDEF)
     {
-      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);
+      dump_generic_node (buffer, def, spc + 2, flags, false);
       pp_string (buffer, ">;");
       newline_and_indent (buffer, spc);
     }
 
-  for (i = 0; i < NUM_VUSES (vuses); i++)
+  FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_VUSE)
     {
-      tree vuse = VUSE_OP (vuses, i);
       pp_string (buffer, "#   VUSE <");
-      dump_generic_node (buffer, vuse, spc + 2, flags, false);
+      dump_generic_node (buffer, use, spc + 2, flags, false);
       pp_string (buffer, ">;");
       newline_and_indent (buffer, spc);
     }
diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c
index e644c35591c6..66980ff6956b 100644
--- a/gcc/tree-sra.c
+++ b/gcc/tree-sra.c
@@ -1397,27 +1397,13 @@ decide_instantiations (void)
 static void
 mark_all_v_defs (tree stmt)
 {
-  v_may_def_optype v_may_defs;
-  v_must_def_optype v_must_defs;
-  size_t i, n;
+  tree sym;
+  ssa_op_iter iter;
 
   get_stmt_operands (stmt);
 
-  v_may_defs = V_MAY_DEF_OPS (stmt_ann (stmt));
-  n = NUM_V_MAY_DEFS (v_may_defs);
-  for (i = 0; i < n; i++)
+  FOR_EACH_SSA_TREE_OPERAND (sym, stmt, iter, SSA_OP_VIRTUAL_DEFS)
     {
-      tree sym = V_MAY_DEF_RESULT (v_may_defs, i);
-      if (TREE_CODE (sym) == SSA_NAME)
-	sym = SSA_NAME_VAR (sym);
-      bitmap_set_bit (vars_to_rename, var_ann (sym)->uid);
-    }
-
-  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);
       if (TREE_CODE (sym) == SSA_NAME)
 	sym = SSA_NAME_VAR (sym);
       bitmap_set_bit (vars_to_rename, var_ann (sym)->uid);
diff --git a/gcc/tree-ssa-alias.c b/gcc/tree-ssa-alias.c
index 8cfc65ad35fc..25c7cf0fa0f8 100644
--- a/gcc/tree-ssa-alias.c
+++ b/gcc/tree-ssa-alias.c
@@ -576,6 +576,8 @@ compute_points_to_and_addr_escape (struct alias_info *ai)
 {
   basic_block bb;
   size_t i;
+  tree op;
+  ssa_op_iter iter;
 
   timevar_push (TV_TREE_PTA);
 
@@ -586,11 +588,6 @@ compute_points_to_and_addr_escape (struct alias_info *ai)
 
       for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si))
 	{
-	  use_optype uses;
-	  def_optype defs;
-	  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);
 	  bool stmt_escapes_p = is_escape_site (stmt, &ai->num_calls_found);
@@ -629,11 +626,8 @@ compute_points_to_and_addr_escape (struct alias_info *ai)
 		  mark_call_clobbered (var);
 		});
 
-	  ann = stmt_ann (stmt);
-	  uses = USE_OPS (ann);
-	  for (i = 0; i < NUM_USES (uses); i++)
+	  FOR_EACH_SSA_TREE_OPERAND (op, stmt, iter, SSA_OP_USE)
 	    {
-	      tree op = USE_OP (uses, i);
 	      var_ann_t v_ann = var_ann (SSA_NAME_VAR (op));
 	      struct ptr_info_def *pi;
 	      bool is_store;
@@ -698,10 +692,8 @@ compute_points_to_and_addr_escape (struct alias_info *ai)
 	  /* Update reference counter for definitions to any
 	     potentially aliased variable.  This is used in the alias
 	     grouping heuristics.  */
-	  defs = DEF_OPS (ann);
-	  for (i = 0; i < NUM_DEFS (defs); i++)
+	  FOR_EACH_SSA_TREE_OPERAND (op, stmt, iter, SSA_OP_DEF)
 	    {
-	      tree op = DEF_OP (defs, i);
 	      tree var = SSA_NAME_VAR (op);
 	      var_ann_t ann = var_ann (var);
 	      bitmap_set_bit (ai->written_vars, ann->uid);
@@ -710,25 +702,13 @@ compute_points_to_and_addr_escape (struct alias_info *ai)
 	    }
 
 	  /* 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++)
+	  FOR_EACH_SSA_TREE_OPERAND (op, stmt, iter, SSA_OP_VIRTUAL_DEFS)
 	    {
-	      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);
-	    }
-
 	  /* After promoting variables and computing aliasing we will
 	     need to re-scan most statements.  FIXME: Try to minimize the
 	     number of statements re-scanned.  It's not really necessary to
@@ -2391,6 +2371,7 @@ dump_points_to_info (FILE *file)
   basic_block bb;
   block_stmt_iterator si;
   size_t i;
+  ssa_op_iter iter;
   const char *fname =
     lang_hooks.decl_printable_name (current_function_decl, 2);
 
@@ -2424,12 +2405,11 @@ dump_points_to_info (FILE *file)
 
 	for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si))
 	  {
-	    stmt_ann_t ann = stmt_ann (bsi_stmt (si));
-	    def_optype defs = DEF_OPS (ann);
-	    if (defs)
-	      for (i = 0; i < NUM_DEFS (defs); i++)
-		if (POINTER_TYPE_P (TREE_TYPE (DEF_OP (defs, i))))
-		  dump_points_to_info_for (file, DEF_OP (defs, i));
+	    tree stmt = bsi_stmt (si);
+	    tree def;
+	    FOR_EACH_SSA_TREE_OPERAND (def, stmt, iter, SSA_OP_DEF)
+	      if (POINTER_TYPE_P (TREE_TYPE (def)))
+		dump_points_to_info_for (file, def);
 	  }
     }
 
diff --git a/gcc/tree-ssa-ccp.c b/gcc/tree-ssa-ccp.c
index f8f2ba504bb0..bffc888fc0ed 100644
--- a/gcc/tree-ssa-ccp.c
+++ b/gcc/tree-ssa-ccp.c
@@ -644,11 +644,11 @@ cp_lattice_meet (value val1, value val2)
 static void
 visit_stmt (tree stmt)
 {
-  size_t i;
   stmt_ann_t ann;
-  def_optype defs;
   v_may_def_optype v_may_defs;
   v_must_def_optype v_must_defs;
+  tree def;
+  ssa_op_iter iter;
 
   /* If the statement has already been deemed to be VARYING, don't simulate
      it again.  */
@@ -684,12 +684,11 @@ visit_stmt (tree stmt)
 
   /* Definitions made by statements other than assignments to SSA_NAMEs
      represent unknown modifications to their outputs.  Mark them VARYING.  */
-  else if (NUM_DEFS (defs = DEF_OPS (ann)) != 0)
+  else if (NUM_DEFS (DEF_OPS (ann)) != 0)
     {
       DONT_SIMULATE_AGAIN (stmt) = 1;
-      for (i = 0; i < NUM_DEFS (defs); i++)
+      FOR_EACH_SSA_TREE_OPERAND (def, stmt, iter, SSA_OP_DEF)
 	{
-	  tree def = DEF_OP (defs, i);
 	  def_to_varying (def);
 	}
     }
@@ -712,9 +711,8 @@ visit_stmt (tree stmt)
     }
 
   /* 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));
+  FOR_EACH_SSA_TREE_OPERAND (def, stmt, iter, SSA_OP_VMAYDEF)
+    def_to_varying (def);
     
 }
 
@@ -1187,6 +1185,8 @@ initialize (void)
   edge e;
   basic_block bb;
   sbitmap virtual_var;
+  tree def;
+  ssa_op_iter iter;
 
   /* Worklists of SSA edges.  */
   VARRAY_TREE_INIT (ssa_edges, 20, "ssa_edges");
@@ -1211,11 +1211,6 @@ initialize (void)
     {
       block_stmt_iterator i;
       tree stmt;
-      stmt_ann_t ann;
-      def_optype defs;
-      v_may_def_optype v_may_defs;
-      v_must_def_optype v_must_defs;
-      size_t x;
       int vary;
 
       /* Get the default value for each definition.  */
@@ -1224,33 +1219,22 @@ initialize (void)
 	  vary = 0;
 	  stmt = bsi_stmt (i);
 	  get_stmt_operands (stmt);
-	  ann = stmt_ann (stmt);
-	  defs = DEF_OPS (ann);
-	  for (x = 0; x < NUM_DEFS (defs); x++)
+
+	  /* Get the default value for each DEF and V_MUST_DEF.  */
+	  FOR_EACH_SSA_TREE_OPERAND (def, stmt, iter, 
+				     (SSA_OP_DEF | SSA_OP_VMUSTDEF))
 	    {
-	      tree def = DEF_OP (defs, x);
 	      if (get_value (def)->lattice_val == VARYING)
 		vary = 1;
 	    }
 	  
-	  /* Get the default value for each V_MUST_DEF.  */
-	  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);
-	      if (get_value (v_must_def)->lattice_val == VARYING)
-	        vary = 1;
-	    }
-	  
 	  DONT_SIMULATE_AGAIN (stmt) = vary;
 
 	  /* 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++)
+	  FOR_EACH_SSA_TREE_OPERAND (def, stmt, iter, SSA_OP_VMAYDEF)
 	    {
-	      tree res = V_MAY_DEF_RESULT (v_may_defs, x);
-	      get_value (res)->lattice_val = VARYING;
-	      SET_BIT (virtual_var, SSA_NAME_VERSION (res));
+	      get_value (def)->lattice_val = VARYING;
+	      SET_BIT (virtual_var, SSA_NAME_VERSION (def));
 	    }
 	}
 
@@ -1494,18 +1478,16 @@ static bool
 replace_uses_in (tree stmt, bool *replaced_addresses_p)
 {
   bool replaced = false;
-  use_optype uses;
-  size_t i;
+  use_operand_p use;
+  ssa_op_iter iter;
 
   if (replaced_addresses_p)
     *replaced_addresses_p = false;
 
   get_stmt_operands (stmt);
 
-  uses = STMT_USE_OPS (stmt);
-  for (i = 0; i < NUM_USES (uses); i++)
+  FOR_EACH_SSA_USE_OPERAND (use, stmt, iter, SSA_OP_USE)
     {
-      use_operand_p use = USE_OP_PTR (uses, i);
       value *val = get_value (USE_FROM_PTR (use));
 
       if (val->lattice_val == CONSTANT)
@@ -1575,11 +1557,11 @@ replace_vuse_in (tree stmt, bool *replaced_addresses_p)
 static latticevalue
 likely_value (tree stmt)
 {
-  use_optype uses;
   vuse_optype vuses;
-  size_t i;
   int found_constant = 0;
   stmt_ann_t ann;
+  tree use;
+  ssa_op_iter iter;
 
   /* If the statement makes aliased loads or has volatile operands, it
      won't fold to a constant value.  */
@@ -1594,10 +1576,8 @@ likely_value (tree stmt)
 
   get_stmt_operands (stmt);
 
-  uses = USE_OPS (ann);
-  for (i = 0; i < NUM_USES (uses); i++)
+  FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_USE)
     {
-      tree use = USE_OP (uses, i);
       value *val = get_value (use);
 
       if (val->lattice_val == UNDEFINED)
@@ -1627,7 +1607,7 @@ likely_value (tree stmt)
 	found_constant = 1;
     }
 
-  return ((found_constant || (!uses && !vuses)) ? CONSTANT : VARYING);
+  return ((found_constant || (!USE_OPS (ann) && !vuses)) ? CONSTANT : VARYING);
 }
 
 /* A subroutine of fold_stmt_r.  Attempts to fold *(A+O) to A[X].
@@ -2266,6 +2246,8 @@ set_rhs (tree *stmt_p, tree expr)
   tree stmt = *stmt_p, op;
   enum tree_code code = TREE_CODE (expr);
   stmt_ann_t ann;
+  tree var;
+  ssa_op_iter iter;
 
   /* Verify the constant folded result is valid gimple.  */
   if (TREE_CODE_CLASS (code) == '2')
@@ -2321,33 +2303,10 @@ set_rhs (tree *stmt_p, tree expr)
 
       if (TREE_SIDE_EFFECTS (expr))
 	{
-	  def_optype defs;
-	  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
 	     replacement.  */
-	  defs = DEF_OPS (ann);
-	  for (i = 0; i < NUM_DEFS (defs); i++)
-	    {
-	      tree var = DEF_OP (defs, i);
-	      if (TREE_CODE (var) == SSA_NAME)
-		SSA_NAME_DEF_STMT (var) = *stmt_p;
-	    }
-
-	  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++)
+	  FOR_EACH_SSA_TREE_OPERAND (var, stmt, iter, SSA_OP_ALL_DEFS)
 	    {
-	      tree var = V_MUST_DEF_OP (v_must_defs, i);
 	      if (TREE_CODE (var) == SSA_NAME)
 		SSA_NAME_DEF_STMT (var) = *stmt_p;
 	    }
diff --git a/gcc/tree-ssa-dce.c b/gcc/tree-ssa-dce.c
index 111f5400b9f5..104185888765 100644
--- a/gcc/tree-ssa-dce.c
+++ b/gcc/tree-ssa-dce.c
@@ -276,12 +276,11 @@ mark_operand_necessary (tree op)
 static void
 mark_stmt_if_obviously_necessary (tree stmt, bool aggressive)
 {
-  def_optype defs;
   v_may_def_optype v_may_defs;
   v_must_def_optype v_must_defs;
   stmt_ann_t ann;
-  size_t i;
-  tree op;
+  tree op, def;
+  ssa_op_iter iter;
 
   /* Statements that are implicitly live.  Most function calls, asm and return
      statements are required.  Labels and BIND_EXPR nodes are kept because
@@ -370,10 +369,8 @@ mark_stmt_if_obviously_necessary (tree stmt, bool aggressive)
 
   get_stmt_operands (stmt);
 
-  defs = DEF_OPS (ann);
-  for (i = 0; i < NUM_DEFS (defs); i++)
+  FOR_EACH_SSA_TREE_OPERAND (def, stmt, iter, SSA_OP_DEF)
     {
-      tree def = DEF_OP (defs, i);
       if (is_global_var (SSA_NAME_VAR (def)))
 	{
 	  mark_stmt_necessary (stmt, true);
@@ -627,30 +624,18 @@ propagate_necessity (struct edge_list *el)
 	  /* Propagate through the operands.  Examine all the USE, VUSE and
 	     V_MAY_DEF operands in this statement.  Mark all the statements 
 	     which feed this statement's uses as necessary.  */
-	  vuse_optype vuses;
-	  v_may_def_optype v_may_defs;
-	  use_optype uses;
-	  stmt_ann_t ann;
-	  size_t k;
+	  ssa_op_iter iter;
+	  tree use;
 
 	  get_stmt_operands (i);
-	  ann = stmt_ann (i);
-
-	  uses = USE_OPS (ann);
-	  for (k = 0; k < NUM_USES (uses); k++)
-	    mark_operand_necessary (USE_OP (uses, k));
-
-	  vuses = VUSE_OPS (ann);
-	  for (k = 0; k < NUM_VUSES (vuses); k++)
-	    mark_operand_necessary (VUSE_OP (vuses, k));
 
 	  /* The operands of V_MAY_DEF expressions are also needed as they
 	     represent potential definitions that may reach this
 	     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));
+
+	  FOR_EACH_SSA_TREE_OPERAND (use, i, iter, SSA_OP_ALL_USES)
+	    mark_operand_necessary (use);
 	}
     }
 }
diff --git a/gcc/tree-ssa-dom.c b/gcc/tree-ssa-dom.c
index fb66922cd8ea..0660cc6952d7 100644
--- a/gcc/tree-ssa-dom.c
+++ b/gcc/tree-ssa-dom.c
@@ -253,7 +253,7 @@ static void restore_vars_to_original_value (varray_type locals,
 					    varray_type table);
 static void restore_currdefs_to_original_value (varray_type locals,
 						unsigned limit);
-static void register_definitions_for_stmt (stmt_ann_t, varray_type *);
+static void register_definitions_for_stmt (tree, varray_type *);
 static edge single_incoming_edge_ignoring_loop_edges (basic_block);
 
 /* Local version of fold that doesn't introduce cruft.  */
@@ -2698,41 +2698,16 @@ static 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_v_may_defs;
-  vuse_optype vuses;
-  v_may_def_optype v_may_defs;
-  use_optype uses;
-
-  uses = USE_OPS (ann);
-  num_uses = NUM_USES (uses);
-  for (i = 0; i < num_uses; i++)
-    {
-      use_operand_p op_p = USE_OP_PTR (uses, i);
-      if (TREE_CODE (USE_FROM_PTR (op_p)) == SSA_NAME)
-	may_have_exposed_new_symbols
-	  |= cprop_operand (stmt, op_p, const_and_copies);
-    }
+  use_operand_p op_p;
+  ssa_op_iter iter;
 
-  vuses = VUSE_OPS (ann);
-  num_vuses = NUM_VUSES (vuses);
-  for (i = 0; i < num_vuses; i++)
+  FOR_EACH_SSA_USE_OPERAND (op_p, stmt, iter, SSA_OP_ALL_USES)
     {
-      use_operand_p op_p = VUSE_OP_PTR (vuses, i);
       if (TREE_CODE (USE_FROM_PTR (op_p)) == SSA_NAME)
 	may_have_exposed_new_symbols
 	  |= cprop_operand (stmt, op_p, const_and_copies);
     }
 
-  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++)
-    {
-      use_operand_p op_p = V_MAY_DEF_OP_PTR (v_may_defs, i);
-      if (TREE_CODE (USE_FROM_PTR (op_p)) == SSA_NAME)
-	may_have_exposed_new_symbols
-	  |= cprop_operand (stmt, op_p, const_and_copies);
-    }
   return may_have_exposed_new_symbols;
 }
 
@@ -2830,7 +2805,7 @@ optimize_stmt (struct dom_walk_data *walk_data, basic_block bb,
 				   may_optimize_p,
 				   ann);
 
-  register_definitions_for_stmt (ann, &bd->block_defs);
+  register_definitions_for_stmt (stmt, &bd->block_defs);
 
   /* If STMT is a COND_EXPR and it was modified, then we may know
      where it goes.  If that is the case, then mark the CFG as altered.
@@ -3373,39 +3348,17 @@ avail_expr_eq (const void *p1, const void *p2)
    and CURRDEFS.  */
 
 static void
-register_definitions_for_stmt (stmt_ann_t ann, varray_type *block_defs_p)
+register_definitions_for_stmt (tree stmt, varray_type *block_defs_p)
 {
-  def_optype defs;
-  v_may_def_optype v_may_defs;
-  v_must_def_optype v_must_defs;
-  unsigned int i;
+  tree def;
+  ssa_op_iter iter;
 
-  defs = DEF_OPS (ann);
-  for (i = 0; i < NUM_DEFS (defs); i++)
+  FOR_EACH_SSA_TREE_OPERAND (def, stmt, iter, SSA_OP_ALL_DEFS)
     {
-      tree def = DEF_OP (defs, i);
 
       /* FIXME: We shouldn't be registering new defs if the variable
 	 doesn't need to be renamed.  */
       register_new_def (def, block_defs_p);
     }
-
-  /* Register new virtual definitions made by the statement.  */
-  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 (V_MUST_DEF_OP (v_must_defs, i), block_defs_p);
-    }
 }
 
diff --git a/gcc/tree-ssa-live.c b/gcc/tree-ssa-live.c
index 6833c6f1eda9..014ec2d55262 100644
--- a/gcc/tree-ssa-live.c
+++ b/gcc/tree-ssa-live.c
@@ -325,16 +325,11 @@ create_ssa_var_map (int flags)
   tree dest, use;
   tree stmt;
   stmt_ann_t ann;
-  use_optype uses;
-  def_optype defs;
-  unsigned x;
   var_map map;
+  ssa_op_iter iter;
 #ifdef ENABLE_CHECKING
   sbitmap used_in_real_ops;
   sbitmap used_in_virtual_ops;
-  vuse_optype vuses;
-  v_may_def_optype v_may_defs;
-  v_must_def_optype v_must_defs;
 #endif
 
   map = init_var_map (num_ssa_names + 1);
@@ -378,10 +373,8 @@ create_ssa_var_map (int flags)
 	  ann = stmt_ann (stmt);
 
 	  /* Register USE and DEF operands in each statement.  */
-	  uses = USE_OPS (ann);
-	  for (x = 0; x < NUM_USES (uses); x++)
+	  FOR_EACH_SSA_TREE_OPERAND (use , stmt, iter, SSA_OP_USE)
 	    {
-	      use = USE_OP (uses, x);
 	      register_ssa_partition (map, use, true);
 
 #ifdef ENABLE_CHECKING
@@ -389,10 +382,8 @@ create_ssa_var_map (int flags)
 #endif
 	    }
 
-	  defs = DEF_OPS (ann);
-	  for (x = 0; x < NUM_DEFS (defs); x++)
+	  FOR_EACH_SSA_TREE_OPERAND (dest, stmt, iter, SSA_OP_DEF)
 	    {
-	      dest = DEF_OP (defs, x);
 	      register_ssa_partition (map, dest, false);
 
 #ifdef ENABLE_CHECKING
@@ -402,26 +393,12 @@ create_ssa_var_map (int flags)
 
 #ifdef ENABLE_CHECKING
 	  /* Validate that virtual ops don't get used in funny ways.  */
-	  vuses = VUSE_OPS (ann);
-	  for (x = 0; x < NUM_VUSES (vuses); x++)
+	  FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, 
+				     SSA_OP_VIRTUAL_USES | SSA_OP_VMUSTDEF)
 	    {
-	      tree var = VUSE_OP (vuses, x);
-	      SET_BIT (used_in_virtual_ops, var_ann (SSA_NAME_VAR (var))->uid);
+	      SET_BIT (used_in_virtual_ops, var_ann (SSA_NAME_VAR (use))->uid);
 	    }
 
-	  v_may_defs = V_MAY_DEF_OPS (ann);
-	  for (x = 0; x < NUM_V_MAY_DEFS (v_may_defs); x++)
-	    {
-	      tree var = V_MAY_DEF_OP (v_may_defs, x);
-	      SET_BIT (used_in_virtual_ops, var_ann (SSA_NAME_VAR (var))->uid);
-	    }
-	    
-	  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_BIT (used_in_virtual_ops, var_ann (SSA_NAME_VAR (var))->uid);
-	    }	    
 #endif /* ENABLE_CHECKING */
 
 	  mark_all_vars_used (bsi_stmt_ptr (bsi));
@@ -579,7 +556,7 @@ tree_live_info_p
 calculate_live_on_entry (var_map map)
 {
   tree_live_info_p live;
-  int num, i;
+  int i;
   basic_block bb;
   bitmap saw_def;
   tree phi, var, stmt;
@@ -587,9 +564,12 @@ calculate_live_on_entry (var_map map)
   edge e;
   varray_type stack;
   block_stmt_iterator bsi;
-  use_optype uses;
-  def_optype defs;
   stmt_ann_t ann;
+  ssa_op_iter iter;
+#ifdef ENABLE_CHECKING
+  int num;
+#endif
+
 
   saw_def = BITMAP_XMALLOC ();
 
@@ -636,19 +616,13 @@ calculate_live_on_entry (var_map map)
 	  get_stmt_operands (stmt);
 	  ann = stmt_ann (stmt);
 
-	  uses = USE_OPS (ann);
-	  num = NUM_USES (uses);
-	  for (i = 0; i < num; i++)
+	  FOR_EACH_SSA_TREE_OPERAND (op, stmt, iter, SSA_OP_USE)
 	    {
-	      op = USE_OP (uses, i);
 	      add_livein_if_notdef (live, saw_def, op, bb);
 	    }
 
-	  defs = DEF_OPS (ann);
-	  num = NUM_DEFS (defs);
-	  for (i = 0; i < num; i++)
+	  FOR_EACH_SSA_TREE_OPERAND (op, stmt, iter, SSA_OP_DEF)
 	    {
-	      op = DEF_OP (defs, i);
 	      set_if_valid (map, saw_def, op);
 	    }
 	}
@@ -1332,12 +1306,11 @@ build_tree_conflict_graph (tree_live_info_p liveinfo, tpa_p tpa,
   conflict_graph graph;
   var_map map;
   bitmap live;
-  int num, x, y, i;
+  int x, y, i;
   basic_block bb;
   varray_type partition_link, tpa_to_clear, tpa_nodes;
-  def_optype defs;
-  use_optype uses;
   unsigned l;
+  ssa_op_iter iter;
 
   map = live_var_map (liveinfo);
   graph = conflict_graph_new (num_var_partitions (map));
@@ -1415,20 +1388,13 @@ build_tree_conflict_graph (tree_live_info_p liveinfo, tpa_p tpa,
 	  if (!is_a_copy)
 	    {
 	      tree var;
-
-	      defs = DEF_OPS (ann);
-	      num = NUM_DEFS (defs);
-	      for (x = 0; x < num; x++)
+	      FOR_EACH_SSA_TREE_OPERAND (var, stmt, iter, SSA_OP_DEF)
 		{
-		  var = DEF_OP (defs, x);
 		  add_conflicts_if_valid (tpa, graph, map, live, var);
 		}
 
-	      uses = USE_OPS (ann);
-	      num = NUM_USES (uses);
-	      for (x = 0; x < num; x++)
+	      FOR_EACH_SSA_TREE_OPERAND (var, stmt, iter, SSA_OP_USE)
 		{
-		  var = USE_OP (uses, x);
 		  set_if_valid (map, live, var);
 		}
 	    }
diff --git a/gcc/tree-ssa-loop-im.c b/gcc/tree-ssa-loop-im.c
index de2540aa4f2c..c5de645234c5 100644
--- a/gcc/tree-ssa-loop-im.c
+++ b/gcc/tree-ssa-loop-im.c
@@ -406,11 +406,8 @@ determine_max_movement (tree stmt, bool must_preserve_exec)
   struct loop *loop = bb->loop_father;
   struct loop *level;
   struct lim_aux_data *lim_data = LIM_DATA (stmt);
-  use_optype uses;
-  vuse_optype vuses;
-  v_may_def_optype v_may_defs;
-  stmt_ann_t ann = stmt_ann (stmt);
-  unsigned i;
+  tree val;
+  ssa_op_iter iter;
   
   if (must_preserve_exec)
     level = ALWAYS_EXECUTED_IN (bb);
@@ -418,19 +415,12 @@ determine_max_movement (tree stmt, bool must_preserve_exec)
     level = superloop_at_depth (loop, 1);
   lim_data->max_loop = level;
 
-  uses = USE_OPS (ann);
-  for (i = 0; i < NUM_USES (uses); i++)
-    if (!add_dependency (USE_OP (uses, i), lim_data, loop, true))
-      return false;
-
-  vuses = VUSE_OPS (ann);
-  for (i = 0; i < NUM_VUSES (vuses); i++)
-    if (!add_dependency (VUSE_OP (vuses, i), lim_data, loop, false))
+  FOR_EACH_SSA_TREE_OPERAND (val, stmt, iter, SSA_OP_USE)
+    if (!add_dependency (val, lim_data, loop, true))
       return false;
 
-  v_may_defs = V_MAY_DEF_OPS (ann);
-  for (i = 0; i < NUM_V_MAY_DEFS (v_may_defs); i++)
-    if (!add_dependency (V_MAY_DEF_OP (v_may_defs, i), lim_data, loop, false))
+  FOR_EACH_SSA_TREE_OPERAND (val, stmt, iter, SSA_OP_VIRTUAL_USES)
+    if (!add_dependency (val, lim_data, loop, false))
       return false;
 
   lim_data->cost += stmt_cost (stmt);
@@ -926,10 +916,10 @@ single_reachable_address (struct loop *loop, tree stmt,
   unsigned in_queue = 1;
   dataflow_t df;
   unsigned i, n;
-  v_may_def_optype v_may_defs;
-  vuse_optype vuses;
   struct sra_data sra_data;
   tree call;
+  tree val;
+  ssa_op_iter iter;
 
   sbitmap_zero (seen);
 
@@ -970,15 +960,9 @@ single_reachable_address (struct loop *loop, tree stmt,
 
 	  /* Traverse also definitions of the VUSES (there may be other
 	     distinct from the one we used to get to this statement).  */
-	  v_may_defs = STMT_V_MAY_DEF_OPS (stmt);
-	  for (i = 0; i < NUM_V_MAY_DEFS (v_may_defs); i++)
-	    maybe_queue_var (V_MAY_DEF_OP (v_may_defs, i), loop,
-			     seen, queue, &in_queue);
+	  FOR_EACH_SSA_TREE_OPERAND (val, stmt, iter, SSA_OP_VIRTUAL_USES)
+	    maybe_queue_var (val, loop, seen, queue, &in_queue);
 
-	  vuses = STMT_VUSE_OPS (stmt);
-	  for (i = 0; i < NUM_VUSES (vuses); i++)
-	    maybe_queue_var (VUSE_OP (vuses, i), loop,
-			     seen, queue, &in_queue);
 	  break;
 
 	case PHI_NODE:
@@ -1029,32 +1013,15 @@ fail:
 static void
 rewrite_mem_refs (tree tmp_var, struct mem_ref *mem_refs)
 {
-  v_may_def_optype v_may_defs;
-  v_must_def_optype v_must_defs;
-  vuse_optype vuses;
-  unsigned i;
   tree var;
+  ssa_op_iter iter;
 
   for (; mem_refs; mem_refs = mem_refs->next)
     {
-      v_may_defs = STMT_V_MAY_DEF_OPS (mem_refs->stmt);
-      for (i = 0; i < NUM_V_MAY_DEFS (v_may_defs); 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 = STMT_V_MUST_DEF_OPS (mem_refs->stmt);
-      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);
-	}
-
-      vuses = STMT_VUSE_OPS (mem_refs->stmt);
-      for (i = 0; i < NUM_VUSES (vuses); i++)
+      FOR_EACH_SSA_TREE_OPERAND (var, mem_refs->stmt, iter,
+				 (SSA_OP_VIRTUAL_DEFS | SSA_OP_VUSE))
 	{
-	  var = SSA_NAME_VAR (VUSE_OP (vuses, i));
+	  var = SSA_NAME_VAR (var);
 	  bitmap_set_bit (vars_to_rename, var_ann (var)->uid);
 	}
 
diff --git a/gcc/tree-ssa-loop-manip.c b/gcc/tree-ssa-loop-manip.c
index e096d265f21f..edb821d24f72 100644
--- a/gcc/tree-ssa-loop-manip.c
+++ b/gcc/tree-ssa-loop-manip.c
@@ -236,27 +236,14 @@ find_uses_to_rename_use (basic_block bb, tree use, bitmap *use_blocks)
 static void
 find_uses_to_rename_stmt (tree stmt, bitmap *use_blocks)
 {
-  use_optype uses;
-  vuse_optype vuses;
-  v_may_def_optype v_may_defs;
-  stmt_ann_t ann;
-  unsigned i;
+  ssa_op_iter iter;
+  tree var;
   basic_block bb = bb_for_stmt (stmt);
 
   get_stmt_operands (stmt);
-  ann = stmt_ann (stmt);
-
-  uses = USE_OPS (ann);
-  for (i = 0; i < NUM_USES (uses); i++)
-    find_uses_to_rename_use (bb, USE_OP (uses, i), use_blocks);
-
-  vuses = VUSE_OPS (ann);
-  for (i = 0; i < NUM_VUSES (vuses); i++)
-    find_uses_to_rename_use (bb, VUSE_OP (vuses, i),use_blocks);
 
-  v_may_defs = V_MAY_DEF_OPS (ann);
-  for (i = 0; i < NUM_V_MAY_DEFS (v_may_defs); i++)
-    find_uses_to_rename_use (bb, V_MAY_DEF_OP (v_may_defs, i), use_blocks);
+  FOR_EACH_SSA_TREE_OPERAND (var, stmt, iter, SSA_OP_ALL_USES)
+    find_uses_to_rename_use (bb, var, use_blocks);
 }
 
 /* Marks names that are used outside of the loop they are defined in
@@ -363,26 +350,13 @@ check_loop_closed_ssa_use (basic_block bb, tree use)
 static void
 check_loop_closed_ssa_stmt (basic_block bb, tree stmt)
 {
-  use_optype uses;
-  vuse_optype vuses;
-  v_may_def_optype v_may_defs;
-  stmt_ann_t ann;
-  unsigned i;
+  ssa_op_iter iter;
+  tree var;
 
   get_stmt_operands (stmt);
-  ann = stmt_ann (stmt);
-
-  uses = USE_OPS (ann);
-  for (i = 0; i < NUM_USES (uses); i++)
-    check_loop_closed_ssa_use (bb, USE_OP (uses, i));
-
-  vuses = VUSE_OPS (ann);
-  for (i = 0; i < NUM_VUSES (vuses); i++)
-    check_loop_closed_ssa_use (bb, VUSE_OP (vuses, i));
 
-  v_may_defs = V_MAY_DEF_OPS (ann);
-  for (i = 0; i < NUM_V_MAY_DEFS (v_may_defs); i++)
-    check_loop_closed_ssa_use (bb, V_MAY_DEF_OP (v_may_defs, i));
+  FOR_EACH_SSA_TREE_OPERAND (var, stmt, iter, SSA_OP_ALL_USES)
+    check_loop_closed_ssa_use (bb, var);
 }
 
 /* Checks that invariants of the loop closed ssa form are preserved.  */
diff --git a/gcc/tree-ssa-operands.c b/gcc/tree-ssa-operands.c
index 5e49683f0f70..c57d486c21cc 100644
--- a/gcc/tree-ssa-operands.c
+++ b/gcc/tree-ssa-operands.c
@@ -114,11 +114,15 @@ 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
 /* Used to make sure operand construction is working on the proper stmt.  */
 tree check_build_stmt;
 #endif
 
+def_operand_p NULL_DEF_OPERAND_P = { NULL };
+use_operand_p NULL_USE_OPERAND_P = { NULL };
+
 static void note_addressable (tree, stmt_ann_t);
 static void get_expr_operands (tree, tree *, int);
 static void get_asm_expr_operands (tree);
diff --git a/gcc/tree-ssa-operands.h b/gcc/tree-ssa-operands.h
index 72aa001a29d8..50459e507f65 100644
--- a/gcc/tree-ssa-operands.h
+++ b/gcc/tree-ssa-operands.h
@@ -36,6 +36,8 @@ typedef struct use_operand_ptr GTY(())
   tree * GTY((skip(""))) use;
 } use_operand_p;
 
+extern def_operand_p NULL_DEF_OPERAND_P;
+extern use_operand_p NULL_USE_OPERAND_P;
 
 /* This represents the DEF operands of a stmt.  */
 typedef struct def_optype_d GTY(())
@@ -184,4 +186,76 @@ extern void get_stmt_operands (tree);
 extern void copy_virtual_operands (tree, tree);
 extern void create_ssa_artficial_load_stmt (stmt_operands_p, tree);
 
+
+/* This structure is used in the operand iterator loops.  It contains the 
+   items required to determine which operand is retreived next.  During
+   optimization, this structure is scalarized, and any unused fields are 
+   optimized away, resulting in little overhead.  */
+
+typedef struct ssa_operand_iterator_d
+{
+  int num_use;
+  int num_def;
+  int num_vuse;
+  int num_v_mayu;
+  int num_v_mayd;
+  int num_v_must;
+  int use_i;
+  int def_i;
+  int vuse_i;
+  int v_mayu_i;
+  int v_mayd_i;
+  int v_must_i;
+  stmt_operands_p ops;
+  bool done;
+} ssa_op_iter;
+
+/* These flags are used to determine which operands are returned during 
+   execution of the loop.  */
+#define SSA_OP_USE		0x01	/* Real USE operands.  */
+#define SSA_OP_DEF		0x02	/* Real DEF operands.  */
+#define SSA_OP_VUSE		0x04	/* VUSE operands.  */
+#define SSA_OP_VMAYUSE		0x08	/* USE portion of V_MAY_DEFS.  */
+#define SSA_OP_VMAYDEF		0x10	/* DEF portion of V_MAY_DEFS.  */
+#define SSA_OP_VMUSTDEF		0x20	/* V_MUST_DEF defintions.  */
+
+/* These are commonly grouped operand flags.  */
+#define SSA_OP_VIRTUAL_USES	(SSA_OP_VUSE | SSA_OP_VMAYUSE)
+#define SSA_OP_VIRTUAL_DEFS	(SSA_OP_VMAYDEF | SSA_OP_VMUSTDEF)
+#define SSA_OP_ALL_USES		(SSA_OP_VIRTUAL_USES | SSA_OP_USE)
+#define SSA_OP_ALL_DEFS		(SSA_OP_VIRTUAL_DEFS | SSA_OP_DEF)
+#define SSA_OP_ALL_OPERANDS	(SSA_OP_ALL_USES | SSA_OP_ALL_DEFS)
+
+/* This macro executes a loop over the operands of STMT specified in FLAG, 
+   returning each operand as a 'tree' in the variable TREEVAR.  ITER is an
+   ssa_op_iter structure used to control the loop.  */
+#define FOR_EACH_SSA_TREE_OPERAND(TREEVAR, STMT, ITER, FLAGS)	\
+  for (TREEVAR = op_iter_init_tree (&(ITER), STMT, FLAGS);	\
+       !op_iter_done (&(ITER));					\
+       TREEVAR = op_iter_next_tree (&(ITER)))
+
+/* This macro executes a loop over the operands of STMT specified in FLAG, 
+   returning each operand as a 'use_operand_p' in the variable USEVAR.  
+   ITER is an ssa_op_iter structure used to control the loop.  */
+#define FOR_EACH_SSA_USE_OPERAND(USEVAR, STMT, ITER, FLAGS)	\
+  for (USEVAR = op_iter_init_use (&(ITER), STMT, FLAGS);	\
+       !op_iter_done (&(ITER));					\
+       USEVAR = op_iter_next_use (&(ITER)))
+
+/* This macro executes a loop over the operands of STMT specified in FLAG, 
+   returning each operand as a 'def_operand_p' in the variable DEFVAR.  
+   ITER is an ssa_op_iter structure used to control the loop.  */
+#define FOR_EACH_SSA_DEF_OPERAND(DEFVAR, STMT, ITER, FLAGS)	\
+  for (DEFVAR = op_iter_init_def (&(ITER), STMT, FLAGS);	\
+       !op_iter_done (&(ITER));					\
+       DEFVAR = op_iter_next_def (&(ITER)))
+
+/* This macro executes a loop over the V_MAY_DEF operands of STMT.  The def
+   and use for each V_MAY_DEF is returned in DEFVAR and USEVAR. 
+   ITER is an ssa_op_iter structure used to control the loop.  */
+#define FOR_EACH_SSA_MAYDEF_OPERAND(DEFVAR, USEVAR, STMT, ITER)	\
+  for (op_iter_init_maydef (&(ITER), STMT, &(USEVAR), &(DEFVAR));	\
+       !op_iter_done (&(ITER));					\
+       op_iter_next_maydef (&(USEVAR), &(DEFVAR), &(ITER)))
+
 #endif  /* GCC_TREE_SSA_OPERANDS_H  */
diff --git a/gcc/tree-ssa.c b/gcc/tree-ssa.c
index 743c08433668..46068e5c99e6 100644
--- a/gcc/tree-ssa.c
+++ b/gcc/tree-ssa.c
@@ -504,6 +504,8 @@ verify_ssa (void)
   size_t i;
   basic_block bb;
   basic_block *definition_block = xcalloc (num_ssa_names, sizeof (basic_block));
+  ssa_op_iter iter;
+  tree op;
 
   timevar_push (TV_TREE_SSA_VERIFY);
 
@@ -528,43 +530,26 @@ verify_ssa (void)
       for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
 	{
 	  tree stmt;
-	  stmt_ann_t ann;
-	  unsigned int j;
-	  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);
 
-	  v_may_defs = V_MAY_DEF_OPS (ann);
-	  if (ann->makes_aliased_stores && NUM_V_MAY_DEFS (v_may_defs) == 0)
+	  if (stmt_ann (stmt)->makes_aliased_stores 
+	      && NUM_V_MAY_DEFS (STMT_V_MAY_DEF_OPS (stmt)) == 0)
 	    {
 	      error ("Statement makes aliased stores, but has no V_MAY_DEFS");
 	      debug_generic_stmt (stmt);
 	      goto err;
 	    }
 	    
-	  for (j = 0; j < NUM_V_MAY_DEFS (v_may_defs); j++)
+	  FOR_EACH_SSA_TREE_OPERAND (op, stmt, iter, SSA_OP_VIRTUAL_DEFS)
 	    {
-	      tree op = V_MAY_DEF_RESULT (v_may_defs, j);
 	      if (verify_def (bb, definition_block, op, stmt, true))
 		goto err;
 	    }
           
-	  v_must_defs = STMT_V_MUST_DEF_OPS (stmt);
-	  for (j = 0; j < NUM_V_MUST_DEFS (v_must_defs); j++)
+	  FOR_EACH_SSA_TREE_OPERAND (op, stmt, iter, SSA_OP_DEF)
 	    {
-	      tree op = V_MUST_DEF_OP (v_must_defs, j);
-	      if (verify_def (bb, definition_block, op, stmt, true))
-		goto err;
-	    }
-
-	  defs = DEF_OPS (ann);
-	  for (j = 0; j < NUM_DEFS (defs); j++)
-	    {
-	      tree op = DEF_OP (defs, j);
 	      if (verify_def (bb, definition_block, op, stmt, false))
 		goto err;
 	    }
@@ -600,34 +585,16 @@ verify_ssa (void)
       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;
-	  v_may_def_optype v_may_defs;
-	  use_optype uses;
-
-	  vuses = VUSE_OPS (ann); 
-	  for (j = 0; j < NUM_VUSES (vuses); j++)
-	    {
-	      tree op = VUSE_OP (vuses, j);
-	      if (verify_use (bb, definition_block[SSA_NAME_VERSION (op)],
-			      op, stmt, false, true))
-		goto err;
-	    }
 
-	  v_may_defs = V_MAY_DEF_OPS (ann);
-	  for (j = 0; j < NUM_V_MAY_DEFS (v_may_defs); j++)
+	  FOR_EACH_SSA_TREE_OPERAND (op, stmt, iter, SSA_OP_VIRTUAL_USES)
 	    {
-	      tree op = V_MAY_DEF_OP (v_may_defs, j);
 	      if (verify_use (bb, definition_block[SSA_NAME_VERSION (op)],
 			      op, stmt, false, true))
 		goto err;
 	    }
 
-	  uses = USE_OPS (ann);
-	  for (j = 0; j < NUM_USES (uses); j++)
+	  FOR_EACH_SSA_TREE_OPERAND (op, stmt, iter, SSA_OP_USE)
 	    {
-	      tree op = USE_OP (uses, j);
 	      if (verify_use (bb, definition_block[SSA_NAME_VERSION (op)],
 			      op, stmt, false, false))
 		goto err;
@@ -941,14 +908,13 @@ propagate_into_addr (tree stmt, tree var, tree *x, tree repl)
 static void
 replace_immediate_uses (tree var, tree repl)
 {
-  use_optype uses;
-  vuse_optype vuses;
-  v_may_def_optype v_may_defs;
   int i, j, n;
   dataflow_t df;
   tree stmt;
   stmt_ann_t ann;
   bool mark_new_vars;
+  ssa_op_iter iter;
+  use_operand_p use_p;
 
   df = get_immediate_uses (SSA_NAME_DEF_STMT (var));
   n = num_immediate_uses (df);
@@ -982,25 +948,18 @@ replace_immediate_uses (tree var, tree repl)
 	      propagate_into_addr (stmt, var, &TREE_OPERAND (stmt, 1), repl);
 	    }
 
-	  uses = USE_OPS (ann);
-	  for (j = 0; j < (int) NUM_USES (uses); j++)
-	    if (USE_OP (uses, j) == var)
+	  FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_USE)
+	    if (USE_FROM_PTR (use_p) == var)
 	      {
-		propagate_value (USE_OP_PTR (uses, j), repl);
+		propagate_value (use_p, repl);
 		mark_new_vars = POINTER_TYPE_P (TREE_TYPE (repl));
 	      }
 	}
       else
 	{
-	  vuses = VUSE_OPS (ann);
-	  for (j = 0; j < (int) NUM_VUSES (vuses); j++)
-	    if (VUSE_OP (vuses, j) == var)
-	      propagate_value (VUSE_OP_PTR (vuses, 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);
+	  FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_VIRTUAL_USES)
+	    if (USE_FROM_PTR (use_p) == var)
+	      propagate_value (use_p, repl);
 	}
 
       /* If REPL is a pointer, it may have different memory tags associated
diff --git a/gcc/tree-ssanames.c b/gcc/tree-ssanames.c
index f48c4a0de7ae..d46014a277dd 100644
--- a/gcc/tree-ssanames.c
+++ b/gcc/tree-ssanames.c
@@ -296,25 +296,11 @@ duplicate_ssa_name (tree name, tree stmt)
 void
 release_defs (tree stmt)
 {
-  size_t i;
-  v_may_def_optype v_may_defs;
-  v_must_def_optype v_must_defs;
-  def_optype defs;
-  stmt_ann_t ann;
+  tree def;
+  ssa_op_iter iter;
 
-  ann = stmt_ann (stmt);
-  defs = DEF_OPS (ann);
-  v_may_defs = V_MAY_DEF_OPS (ann);
-  v_must_defs = V_MUST_DEF_OPS (ann);
-
-  for (i = 0; i < NUM_DEFS (defs); i++)
-    release_ssa_name (DEF_OP (defs, i));
-
-  for (i = 0; i < NUM_V_MAY_DEFS (v_may_defs); i++)
-    release_ssa_name (V_MAY_DEF_RESULT (v_may_defs, i));
-
-  for (i = 0; i < NUM_V_MUST_DEFS (v_must_defs); i++)
-    release_ssa_name (V_MUST_DEF_OP (v_must_defs, i));
+  FOR_EACH_SSA_TREE_OPERAND (def, stmt, iter, SSA_OP_ALL_DEFS)
+    release_ssa_name (def);
 }
 
 
diff --git a/gcc/tree-vectorizer.c b/gcc/tree-vectorizer.c
index 34fbb9fde798..770772cc9517 100644
--- a/gcc/tree-vectorizer.c
+++ b/gcc/tree-vectorizer.c
@@ -674,11 +674,6 @@ vect_create_data_ref (tree stmt, block_stmt_iterator *bsi)
   tree vect_ptr_type;
   tree vect_ptr;
   tree addr_ref;
-  v_may_def_optype v_may_defs = STMT_V_MAY_DEF_OPS (stmt);
-  v_must_def_optype v_must_defs = STMT_V_MUST_DEF_OPS (stmt);
-  vuse_optype vuses = STMT_VUSE_OPS (stmt);
-  int nvuses, nv_may_defs, nv_must_defs;
-  int i;
   struct data_reference *dr = STMT_VINFO_DATA_REF (stmt_info);
   tree array_type;
   tree base_addr = NULL_TREE;
@@ -687,6 +682,8 @@ vect_create_data_ref (tree stmt, block_stmt_iterator *bsi)
   tree tag;
   tree addr_expr;
   tree scalar_ptr_type;
+  tree use;
+  ssa_op_iter iter;
 
   /* FORNOW: make sure the data reference is aligned.  */
   vect_align_data_ref (stmt);
@@ -743,27 +740,12 @@ vect_create_data_ref (tree stmt, block_stmt_iterator *bsi)
   
   /* Mark for renaming all aliased variables
      (i.e, the may-aliases of the type-mem-tag) */
-  nvuses = NUM_VUSES (vuses);
-  nv_may_defs = NUM_V_MAY_DEFS (v_may_defs);
-  nv_must_defs = NUM_V_MUST_DEFS (v_must_defs);
-  for (i = 0; i < nvuses; i++)
+  FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter,
+			     (SSA_OP_VIRTUAL_DEFS | SSA_OP_VUSE))
     {
-      tree use = VUSE_OP (vuses, i);
       if (TREE_CODE (use) == SSA_NAME)
         bitmap_set_bit (vars_to_rename, var_ann (SSA_NAME_VAR (use))->uid);
     }
-  for (i = 0; i < nv_may_defs; i++)
-    {
-      tree def = V_MAY_DEF_RESULT (v_may_defs, i);
-      if (TREE_CODE (def) == SSA_NAME)
-        bitmap_set_bit (vars_to_rename, var_ann (SSA_NAME_VAR (def))->uid);
-    }
-  for (i = 0; i < nv_must_defs; i++)
-    {
-      tree def = V_MUST_DEF_OP (v_must_defs, i);
-      if (TREE_CODE (def) == SSA_NAME)
-        bitmap_set_bit (vars_to_rename, var_ann (SSA_NAME_VAR (def))->uid);
-    }
 
   pe = loop_preheader_edge (loop);
 
-- 
GitLab