+2012-08-16  Richard Guenther  <rguenther@suse.de>
+
+       PR middle-end/54146
+       * tree-ssa-loop-niter.c (find_loop_niter_by_eval): Free the
+       exit vector.
+       * ipa-pure-const.c (analyze_function): Use FOR_EACH_LOOP_BREAK.
+       * cfgloop.h (FOR_EACH_LOOP_BREAK): Fix.
+       * tree-ssa-structalias.c (handle_lhs_call): Properly free rhsc.
+       * tree-into-ssa.c (get_ssa_name_ann): Allocate info only when
+       needed.
+       * tree-ssa-loop-im.c (analyze_memory_references): Adjust.
+       (tree_ssa_lim_finalize): Free all mem_refs.
+       * tree-ssa-sccvn.c (extract_and_process_scc_for_name): Free
+       scc when bailing out.
+       * modulo-sched.c (sms_schedule): Use FOR_EACH_LOOP_BREAK.
+       * ira-build.c (loop_with_complex_edge_p): Free loop exit vector.
+       * graphite-sese-to-poly.c (scop_ivs_can_be_represented): Use
+       FOR_EACH_LOOP_BREAK.
+
 2012-08-16  Diego Novillo  <dnovillo@google.com>
 
        PR bootstrap/54281
 
 
 #define FOR_EACH_LOOP_BREAK(LI) \
   { \
-    VEC_free (int, heap, (LI)->to_visit); \
+    VEC_free (int, heap, (LI).to_visit); \
     break; \
   }
 
 
   loop_iterator li;
   loop_p loop;
   gimple_stmt_iterator psi;
+  bool result = true;
 
   FOR_EACH_LOOP (li, loop, 0)
     {
 
          if (TYPE_UNSIGNED (type)
              && TYPE_PRECISION (type) >= TYPE_PRECISION (long_long_integer_type_node))
-           return false;
+           {
+             result = false;
+             break;
+           }
        }
+      if (!result)
+       FOR_EACH_LOOP_BREAK (li);
     }
 
-  return true;
+  return result;
 }
 
 /* Builds the polyhedral representation for a SESE region.  */
 
                    if (dump_file)
                      fprintf (dump_file, "    can not prove finiteness of loop %i\n", loop->num);
                    l->looping =true;
-                   break;
+                   FOR_EACH_LOOP_BREAK (li);
                  }
              scev_finalize ();
            }
 
   edge_iterator ei;
   edge e;
   VEC (edge, heap) *edges;
+  bool res;
 
   FOR_EACH_EDGE (e, ei, loop->header->preds)
     if (e->flags & EDGE_EH)
       return true;
   edges = get_loop_exit_edges (loop);
+  res = false;
   FOR_EACH_VEC_ELT (edge, edges, i, e)
     if (e->flags & EDGE_COMPLEX)
-      return true;
-  return false;
+      {
+       res = true;
+       break;
+      }
+  VEC_free (edge, heap, edges);
+  return res;
 }
 #endif
 
 
           if (dump_file)
             fprintf (dump_file, "SMS reached max limit... \n");
 
-          break;
+         FOR_EACH_LOOP_BREAK (li);
         }
 
       if (dump_file)
 
   unsigned len = VEC_length (ssa_name_info_p, info_for_ssa_name);
   struct ssa_name_info *info;
 
+  /* Re-allocate the vector at most once per update/into-SSA.  */
   if (ver >= len)
-    {
-      unsigned old_len = VEC_length (ssa_name_info_p, info_for_ssa_name);
-      unsigned new_len = num_ssa_names;
+    VEC_safe_grow_cleared (ssa_name_info_p, heap,
+                          info_for_ssa_name, num_ssa_names);
 
-      VEC_reserve (ssa_name_info_p, heap, info_for_ssa_name,
-                  new_len - old_len);
-      while (len++ < new_len)
-       {
-         struct ssa_name_info *info = XCNEW (struct ssa_name_info);
-         info->age = current_info_for_ssa_name_age;
-         VEC_quick_push (ssa_name_info_p, info_for_ssa_name, info);
-       }
+  /* But allocate infos lazily.  */
+  info = VEC_index (ssa_name_info_p, info_for_ssa_name, ver);
+  if (!info)
+    {
+      info = XCNEW (struct ssa_name_info);
+      info->age = current_info_for_ssa_name_age;
+      info->info.need_phi_state = NEED_PHI_STATE_UNKNOWN;
+      VEC_replace (ssa_name_info_p, info_for_ssa_name, ver, info);
     }
 
-  info = VEC_index (ssa_name_info_p, info_for_ssa_name, ver);
   if (info->age < current_info_for_ssa_name_age)
     {
       info->age = current_info_for_ssa_name_age;
 
 /* A function to free the mem_ref object OBJ.  */
 
 static void
-memref_free (void *obj)
+memref_free (struct mem_ref *mem)
 {
-  struct mem_ref *const mem = (struct mem_ref *) obj;
   unsigned i;
   mem_ref_locs_p accs;
 
   unsigned i;
   bitmap empty;
 
-  memory_accesses.refs
-         = htab_create (100, memref_hash, memref_eq, memref_free);
+  memory_accesses.refs = htab_create (100, memref_hash, memref_eq, NULL);
   memory_accesses.refs_list = NULL;
   memory_accesses.refs_in_loop = VEC_alloc (bitmap, heap,
                                            number_of_loops ());
   basic_block bb;
   unsigned i;
   bitmap b;
+  mem_ref_p ref;
 
   free_aux_for_edges ();
 
 
   pointer_map_destroy (lim_aux_data_map);
 
-  VEC_free (mem_ref_p, heap, memory_accesses.refs_list);
   htab_delete (memory_accesses.refs);
 
+  FOR_EACH_VEC_ELT (mem_ref_p, memory_accesses.refs_list, i, ref)
+    memref_free (ref);
+  VEC_free (mem_ref_p, heap, memory_accesses.refs_list);
+
   FOR_EACH_VEC_ELT (bitmap, memory_accesses.refs_in_loop, i, b)
     BITMAP_FREE (b);
   VEC_free (bitmap, heap, memory_accesses.refs_in_loop);
 
   /* Loops with multiple exits are expensive to handle and less important.  */
   if (!flag_expensive_optimizations
       && VEC_length (edge, exits) > 1)
-    return chrec_dont_know;
+    {
+      VEC_free (edge, heap, exits);
+      return chrec_dont_know;
+    }
 
   FOR_EACH_VEC_ELT (edge, exits, i, ex)
     {
 
        fprintf (dump_file, "WARNING: Giving up with SCCVN due to "
                 "SCC size %u exceeding %u\n", VEC_length (tree, scc),
                 (unsigned)PARAM_VALUE (PARAM_SCCVN_MAX_SCC_SIZE));
+
+      VEC_free (tree, heap, scc);
       return false;
     }
 
 
       tmpc.offset = 0;
       tmpc.type = ADDRESSOF;
       VEC_safe_push (ce_s, heap, rhsc, &tmpc);
+      process_all_all_constraints (lhsc, rhsc);
+      VEC_free (ce_s, heap, rhsc);
     }
-
-  process_all_all_constraints (lhsc, rhsc);
+  else
+    process_all_all_constraints (lhsc, rhsc);
 
   VEC_free (ce_s, heap, lhsc);
 }