diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c
index 130a16b..66d8ba5 100644
--- a/gcc/cfgexpand.c
+++ b/gcc/cfgexpand.c
@@ -814,13 +814,12 @@ update_alias_info_with_stack_vars (void)
      contain all members of the partition.  */
   if (decls_to_partitions)
     {
-      unsigned i;
+      tree name;
       hash_set<bitmap> visited;
       bitmap temp = BITMAP_ALLOC (&stack_var_bitmap_obstack);
 
-      for (i = 1; i < num_ssa_names; i++)
+      FOR_EACH_SSAVAR (name)
 	{
-	  tree name = ssa_name (i);
 	  struct ptr_info_def *pi;
 
 	  if (name
@@ -6162,7 +6161,7 @@ pass_expand::execute (function *fun)
   edge_iterator ei;
   edge e;
   rtx_insn *var_seq, *var_ret_seq;
-  unsigned i;
+  tree name;
 
   timevar_push (TV_OUT_OF_SSA);
   rewrite_out_of_ssa (&SA);
@@ -6270,10 +6269,8 @@ pass_expand::execute (function *fun)
 
   /* Now propagate the RTL assignment of each partition to the
      underlying var of each SSA_NAME.  */
-  for (i = 1; i < num_ssa_names; i++)
+  FOR_EACH_SSAVAR (name)
     {
-      tree name = ssa_name (i);
-
       if (!name
 	  /* We might have generated new SSA names in
 	     update_alias_info_with_stack_vars.  They will have a NULL
@@ -6288,9 +6285,8 @@ pass_expand::execute (function *fun)
   /* Clean up RTL of variables that straddle across multiple
      partitions, and check that the rtl of any PARM_DECLs that are not
      cleaned up is that of their default defs.  */
-  for (i = 1; i < num_ssa_names; i++)
+  FOR_EACH_SSAVAR (name)
     {
-      tree name = ssa_name (i);
       int part;
 
       if (!name
diff --git a/gcc/omp-simd-clone.c b/gcc/omp-simd-clone.c
index 467d872..cedd60d 100644
--- a/gcc/omp-simd-clone.c
+++ b/gcc/omp-simd-clone.c
@@ -888,6 +888,7 @@ ipa_simd_modify_function_body (struct cgraph_node *node,
 {
   basic_block bb;
   unsigned int i, j, l;
+  tree name;
 
   /* Re-use the adjustments array, but this time use it to replace
      every function argument use to an offset into the corresponding
@@ -911,9 +912,8 @@ ipa_simd_modify_function_body (struct cgraph_node *node,
     }
 
   l = adjustments.length ();
-  for (i = 1; i < num_ssa_names; i++)
+  FOR_EACH_SSAVAR (name)
     {
-      tree name = ssa_name (i);
       if (name
 	  && SSA_NAME_VAR (name)
 	  && TREE_CODE (SSA_NAME_VAR (name)) == PARM_DECL)
diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c
index 57c8410..09f9f7e 100644
--- a/gcc/tree-cfg.c
+++ b/gcc/tree-cfg.c
@@ -7539,6 +7539,7 @@ dump_function_to_file (tree fndecl, FILE *file, int flags)
   if (fun && fun->decl == fndecl && (fun->curr_properties & PROP_gimple_lcf))
     {
       unsigned ix;
+      tree name;
       ignore_topmost_bind = true;
 
       fprintf (file, "{\n");
@@ -7582,9 +7583,8 @@ dump_function_to_file (tree fndecl, FILE *file, int flags)
 	    any_var = true;
 	  }
       if (gimple_in_ssa_p (cfun))
-	for (ix = 1; ix < num_ssa_names; ++ix)
+	FOR_EACH_SSAVAR (name)
 	  {
-	    tree name = ssa_name (ix);
 	    if (name && !SSA_NAME_VAR (name))
 	      {
 		fprintf (file, "  ");
diff --git a/gcc/tree-into-ssa.c b/gcc/tree-into-ssa.c
index ceafa68..56214b6 100644
--- a/gcc/tree-into-ssa.c
+++ b/gcc/tree-into-ssa.c
@@ -2341,7 +2341,7 @@ pass_build_ssa::execute (function *fun)
 {
   bitmap_head *dfs;
   basic_block bb;
-  unsigned i;
+  tree decl, name;
 
   /* Initialize operand data structures.  */
   init_ssa_operands (fun);
@@ -2385,9 +2385,8 @@ pass_build_ssa::execute (function *fun)
   /* Try to get rid of all gimplifier generated temporaries by making
      its SSA names anonymous.  This way we can garbage collect them
      all after removing unused locals which we do in our TODO.  */
-  for (i = 1; i < num_ssa_names; ++i)
+  FOR_EACH_SSAVAR (name)
     {
-      tree decl, name = ssa_name (i);
       if (!name
 	  || SSA_NAME_IS_DEFAULT_DEF (name))
 	continue;
@@ -3165,7 +3164,7 @@ update_ssa (unsigned update_flags)
   unsigned i = 0;
   bool insert_phi_p;
   sbitmap_iterator sbi;
-  tree sym;
+  tree sym, name;
 
   /* Only one update flag should be set.  */
   gcc_assert (update_flags == TODO_update_ssa
@@ -3284,9 +3283,8 @@ update_ssa (unsigned update_flags)
       prepare_block_for_update (start_bb, insert_phi_p);
 
       if (flag_checking)
-	for (i = 1; i < num_ssa_names; ++i)
+	FOR_EACH_SSAVAR (name)
 	  {
-	    tree name = ssa_name (i);
 	    if (!name
 		|| virtual_operand_p (name))
 	      continue;
diff --git a/gcc/tree-ssa-alias.c b/gcc/tree-ssa-alias.c
index 8051a66..0a55865 100644
--- a/gcc/tree-ssa-alias.c
+++ b/gcc/tree-ssa-alias.c
@@ -450,6 +450,7 @@ void
 dump_alias_info (FILE *file)
 {
   unsigned i;
+  tree ptr;
   const char *funcname
     = lang_hooks.decl_printable_name (current_function_decl, 2);
   tree var;
@@ -471,9 +472,8 @@ dump_alias_info (FILE *file)
 
   fprintf (file, "\n\nFlow-insensitive points-to information\n\n");
 
-  for (i = 1; i < num_ssa_names; i++)
+  FOR_EACH_SSAVAR (ptr)
     {
-      tree ptr = ssa_name (i);
       struct ptr_info_def *pi;
 
       if (ptr == NULL_TREE
diff --git a/gcc/tree-ssa-ccp.c b/gcc/tree-ssa-ccp.c
index 9871304..681da85 100644
--- a/gcc/tree-ssa-ccp.c
+++ b/gcc/tree-ssa-ccp.c
@@ -897,16 +897,15 @@ static bool
 ccp_finalize (bool nonzero_p) 
 {
   bool something_changed;
-  unsigned i;
+  tree name;
 
   do_dbg_cnt ();
 
   /* Derive alignment and misalignment information from partially
      constant pointers in the lattice or nonzero bits from partially
      constant integers.  */
-  for (i = 1; i < num_ssa_names; ++i)
+  FOR_EACH_SSAVAR (name)
     {
-      tree name = ssa_name (i);
       ccp_prop_value_t *val;
       unsigned int tem, align;
 
diff --git a/gcc/tree-ssa-coalesce.c b/gcc/tree-ssa-coalesce.c
index 34c3fa1..9907d55 100644
--- a/gcc/tree-ssa-coalesce.c
+++ b/gcc/tree-ssa-coalesce.c
@@ -954,11 +954,10 @@ build_ssa_conflict_graph (tree_live_info_p liveinfo)
 	 RTL to the same partition.  */
       if (bb == entry)
 	{
-	  unsigned i;
-	  for (i = 1; i < num_ssa_names; i++)
-	    {
-	      tree var = ssa_name (i);
+	  tree var;
 
+	  FOR_EACH_SSAVAR (var)
+	    {
 	      if (!var
 		  || !SSA_NAME_IS_DEFAULT_DEF (var)
 		  || !SSA_NAME_VAR (var)
@@ -1090,7 +1089,6 @@ create_outofssa_var_map (coalesce_list *cl, bitmap used_in_copy)
   var_map map;
   ssa_op_iter iter;
   int v1, v2, cost;
-  unsigned i;
 
   for_all_parms (create_default_def, NULL);
 
@@ -1261,9 +1259,8 @@ create_outofssa_var_map (coalesce_list *cl, bitmap used_in_copy)
   /* Now process result decls and live on entry variables for entry into
      the coalesce list.  */
   first = NULL_TREE;
-  for (i = 1; i < num_ssa_names; i++)
+  FOR_EACH_SSAVAR (var)
     {
-      var = ssa_name (i);
       if (var != NULL_TREE && !virtual_operand_p (var))
         {
 	  coalesce_with_default (var, cl, used_in_copy);
@@ -1805,7 +1802,7 @@ coalesce_ssa_name (void)
   coalesce_list *cl;
   bitmap used_in_copies = BITMAP_ALLOC (NULL);
   var_map map;
-  unsigned int i;
+  tree a;
 
   cl = create_coalesce_list ();
   map = create_outofssa_var_map (cl, used_in_copies);
@@ -1817,10 +1814,8 @@ coalesce_ssa_name (void)
     {
       hash_table<ssa_name_var_hash> ssa_name_hash (10);
 
-      for (i = 1; i < num_ssa_names; i++)
+      FOR_EACH_SSAVAR (a)
 	{
-	  tree a = ssa_name (i);
-
 	  if (a
 	      && SSA_NAME_VAR (a)
 	      && !DECL_IGNORED_P (SSA_NAME_VAR (a))
diff --git a/gcc/tree-ssa-operands.c b/gcc/tree-ssa-operands.c
index eccea2f..3480639 100644
--- a/gcc/tree-ssa-operands.c
+++ b/gcc/tree-ssa-operands.c
@@ -1244,12 +1244,10 @@ void
 dump_immediate_uses (FILE *file)
 {
   tree var;
-  unsigned int x;
 
   fprintf (file, "Immediate_uses: \n\n");
-  for (x = 1; x < num_ssa_names; x++)
+  FOR_EACH_SSAVAR (var)
     {
-      var = ssa_name (x);
       if (!var)
         continue;
       dump_immediate_uses_for (file, var);
diff --git a/gcc/tree-ssa-pre.c b/gcc/tree-ssa-pre.c
index fdb1c2c..3c1d95f 100644
--- a/gcc/tree-ssa-pre.c
+++ b/gcc/tree-ssa-pre.c
@@ -3669,13 +3669,12 @@ compute_avail (void)
   basic_block block, son;
   basic_block *worklist;
   size_t sp = 0;
-  unsigned i;
+  tree name;
 
   /* We pretend that default definitions are defined in the entry block.
      This includes function arguments and the static chain decl.  */
-  for (i = 1; i < num_ssa_names; ++i)
+  FOR_EACH_SSAVAR (name)
     {
-      tree name = ssa_name (i);
       pre_expr e;
       if (!name
 	  || !SSA_NAME_IS_DEFAULT_DEF (name)
diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c
index 21b3d56..d9cb2e7 100644
--- a/gcc/tree-ssa-sccvn.c
+++ b/gcc/tree-ssa-sccvn.c
@@ -4290,7 +4290,7 @@ free_vn_table (vn_tables_t table)
 static void
 init_scc_vn (void)
 {
-  size_t i;
+  tree name;
   int j;
   int *rpo_numbers_temp;
 
@@ -4339,9 +4339,8 @@ init_scc_vn (void)
 
   /* Create the VN_INFO structures, and initialize value numbers to
      TOP or VARYING for parameters.  */
-  for (i = 1; i < num_ssa_names; i++)
+  FOR_EACH_SSAVAR (name)
     {
-      tree name = ssa_name (i);
       if (!name)
 	continue;
 
@@ -4402,9 +4401,10 @@ init_scc_vn (void)
 void
 scc_vn_restore_ssa_info (void)
 {
-  for (unsigned i = 0; i < num_ssa_names; i++)
+  tree name;
+
+  FOR_EACH_SSAVAR (name)
     {
-      tree name = ssa_name (i);
       if (name
 	  && has_VN_INFO (name))
 	{
@@ -4427,7 +4427,7 @@ scc_vn_restore_ssa_info (void)
 void
 free_scc_vn (void)
 {
-  size_t i;
+  tree name;
 
   delete constant_to_value_id;
   constant_to_value_id = NULL;
@@ -4436,9 +4436,8 @@ free_scc_vn (void)
   shared_lookup_references.release ();
   XDELETEVEC (rpo_numbers);
 
-  for (i = 0; i < num_ssa_names; i++)
+  FOR_EACH_SSAVAR (name)
     {
-      tree name = ssa_name (i);
       if (name
 	  && has_VN_INFO (name)
 	  && VN_INFO (name)->needs_insertion)
@@ -4757,6 +4756,7 @@ bool
 run_scc_vn (vn_lookup_kind default_vn_walk_kind_)
 {
   size_t i;
+  tree name;
 
   default_vn_walk_kind = default_vn_walk_kind_;
 
@@ -4797,9 +4797,8 @@ run_scc_vn (vn_lookup_kind default_vn_walk_kind_)
 
   /* Initialize the value ids and prune out remaining VN_TOPs
      from dead code.  */
-  for (i = 1; i < num_ssa_names; ++i)
+  FOR_EACH_SSAVAR (name)
     {
-      tree name = ssa_name (i);
       vn_ssa_aux_t info;
       if (!name)
 	continue;
@@ -4814,9 +4813,8 @@ run_scc_vn (vn_lookup_kind default_vn_walk_kind_)
     }
 
   /* Propagate.  */
-  for (i = 1; i < num_ssa_names; ++i)
+  FOR_EACH_SSAVAR (name)
     {
-      tree name = ssa_name (i);
       vn_ssa_aux_t info;
       if (!name)
 	continue;
@@ -4832,9 +4830,8 @@ run_scc_vn (vn_lookup_kind default_vn_walk_kind_)
   if (dump_file && (dump_flags & TDF_DETAILS))
     {
       fprintf (dump_file, "Value numbers:\n");
-      for (i = 0; i < num_ssa_names; i++)
+      FOR_EACH_SSAVAR (name)
 	{
-	  tree name = ssa_name (i);
 	  if (name
 	      && VN_INFO (name)->visited
 	      && SSA_VAL (name) != name)
diff --git a/gcc/tree-ssa-structalias.c b/gcc/tree-ssa-structalias.c
index fd96c3a..c300650 100644
--- a/gcc/tree-ssa-structalias.c
+++ b/gcc/tree-ssa-structalias.c
@@ -7028,7 +7028,7 @@ static void
 compute_points_to_sets (void)
 {
   basic_block bb;
-  unsigned i;
+  tree ptr;
   varinfo_t vi;
 
   timevar_push (TV_TREE_PTA);
@@ -7077,9 +7077,8 @@ compute_points_to_sets (void)
   cfun->gimple_df->escaped.escaped = 0;
 
   /* Compute the points-to sets for pointer SSA_NAMEs.  */
-  for (i = 0; i < num_ssa_names; ++i)
+  FOR_EACH_SSAVAR (ptr)
     {
-      tree ptr = ssa_name (i);
       if (ptr
 	  && POINTER_TYPE_P (TREE_TYPE (ptr)))
 	find_what_p_points_to (cfun->decl, ptr);
diff --git a/gcc/tree-ssa-ter.c b/gcc/tree-ssa-ter.c
index 2a772b2..50faf81 100644
--- a/gcc/tree-ssa-ter.c
+++ b/gcc/tree-ssa-ter.c
@@ -185,7 +185,7 @@ extern void debug_ter (FILE *, temp_expr_table *);
 static temp_expr_table *
 new_temp_expr_table (var_map map)
 {
-  unsigned x;
+  tree name;
 
   temp_expr_table *t = XNEW (struct temp_expr_table);
   t->map = map;
@@ -201,10 +201,9 @@ new_temp_expr_table (var_map map)
 
   t->replaceable_expressions = NULL;
   t->num_in_part = XCNEWVEC (int, num_var_partitions (map));
-  for (x = 1; x < num_ssa_names; x++)
+  FOR_EACH_SSAVAR (name)
     {
       int p;
-      tree name = ssa_name (x);
       if (!name)
         continue;
       p = var_to_partition (map, name);
diff --git a/gcc/tree-ssanames.h b/gcc/tree-ssanames.h
index 8e66ce6..8b8c07e 100644
--- a/gcc/tree-ssanames.h
+++ b/gcc/tree-ssanames.h
@@ -62,6 +62,64 @@ struct GTY ((variable_size)) range_info_def {
 #define num_ssa_names (vec_safe_length (cfun->gimple_df->ssa_names))
 #define ssa_name(i) ((*cfun->gimple_df->ssa_names)[(i)])
 
+/* The iterator for ssa names in a function.  */
+class ssa_iterator
+{
+public:
+  ssa_iterator (unsigned p_ssa_names_no,
+		vec<tree_node*, va_gc> *p_ssanames,
+		tree *p_var);
+  ~ssa_iterator () {}
+
+  inline void next ();
+  inline bool get (tree *);
+
+private:
+  /* The index of the ssa visiting.  */
+  unsigned m_idx;
+  /* The number of ssa in the function.  */
+  unsigned m_ssa_names_count;
+  /* Vector containing the ssa names in the function.  */
+  vec<tree_node*, va_gc> *m_ssanames;
+};
+
+inline
+ssa_iterator::ssa_iterator (unsigned p_ssa_names_count,
+			    vec<tree_node*, va_gc> *p_ssanames,
+			    tree *p_var) : m_idx (0),
+  m_ssa_names_count (p_ssa_names_count),
+  m_ssanames (p_ssanames)
+{
+  this->get (p_var);
+}
+
+inline bool
+ssa_iterator::get (tree *p_var)
+{
+  if (this->m_idx < this->m_ssa_names_count)
+    {
+      *p_var = (*m_ssanames)[this->m_idx];
+      return true;
+    }
+  else
+    {
+      *p_var = NULL_TREE;
+      return false;
+    }
+}
+
+inline void
+ssa_iterator::next ()
+{
+  this->m_idx += 1;
+}
+
+#define FOR_EACH_SSAVAR(VAR)					\
+  for (ssa_iterator si (num_ssa_names, cfun->gimple_df->ssa_names,	\
+		       &VAR);						\
+       si.get (&VAR);							\
+       si.next ())
+
 /* Sets the value range to SSA.  */
 extern void set_range_info (tree, enum value_range_type, const wide_int_ref &,
 			    const wide_int_ref &);
