Index: trunk/gcc/cfg.c
===================================================================
--- trunk.orig/gcc/cfg.c	2015-10-26 15:27:42.150921714 +0100
+++ trunk/gcc/cfg.c	2015-10-26 15:32:23.679086458 +0100
@@ -88,35 +88,35 @@ init_flow (struct function *the_fun)
    without actually removing it from the pred/succ arrays.  */
 
 static void
-free_edge (edge e)
+free_edge (function *fn, edge e)
 {
-  n_edges_for_fn (cfun)--;
+  n_edges_for_fn (fn)--;
   ggc_free (e);
 }
 
 /* Free the memory associated with the edge structures.  */
 
 void
-clear_edges (void)
+clear_edges (struct function *fn)
 {
   basic_block bb;
   edge e;
   edge_iterator ei;
 
-  FOR_EACH_BB_FN (bb, cfun)
+  FOR_EACH_BB_FN (bb, fn)
     {
       FOR_EACH_EDGE (e, ei, bb->succs)
-	free_edge (e);
+	free_edge (fn, e);
       vec_safe_truncate (bb->succs, 0);
       vec_safe_truncate (bb->preds, 0);
     }
 
-  FOR_EACH_EDGE (e, ei, ENTRY_BLOCK_PTR_FOR_FN (cfun)->succs)
-    free_edge (e);
-  vec_safe_truncate (EXIT_BLOCK_PTR_FOR_FN (cfun)->preds, 0);
-  vec_safe_truncate (ENTRY_BLOCK_PTR_FOR_FN (cfun)->succs, 0);
+  FOR_EACH_EDGE (e, ei, ENTRY_BLOCK_PTR_FOR_FN (fn)->succs)
+    free_edge (fn, e);
+  vec_safe_truncate (EXIT_BLOCK_PTR_FOR_FN (fn)->preds, 0);
+  vec_safe_truncate (ENTRY_BLOCK_PTR_FOR_FN (fn)->succs, 0);
 
-  gcc_assert (!n_edges_for_fn (cfun));
+  gcc_assert (!n_edges_for_fn (fn));
 }
 
 /* Allocate memory for basic_block.  */
@@ -350,7 +350,7 @@ remove_edge_raw (edge e)
   disconnect_src (e);
   disconnect_dest (e);
 
-  free_edge (e);
+  free_edge (cfun, e);
 }
 
 /* Redirect an edge's successor from one block to another.  */
Index: trunk/gcc/cfg.h
===================================================================
--- trunk.orig/gcc/cfg.h	2015-10-26 15:27:42.150921714 +0100
+++ trunk/gcc/cfg.h	2015-10-26 15:30:14.536634739 +0100
@@ -74,8 +74,8 @@ struct GTY(()) control_flow_graph {
 };
 
 
-extern void init_flow (struct function *);
-extern void clear_edges (void);
+extern void init_flow (function *);
+extern void clear_edges (function *);
 extern basic_block alloc_block (void);
 extern void link_block (basic_block, basic_block);
 extern void unlink_block (basic_block);
Index: trunk/gcc/cfgexpand.c
===================================================================
--- trunk.orig/gcc/cfgexpand.c	2015-10-26 15:27:42.150921714 +0100
+++ trunk/gcc/cfgexpand.c	2015-10-26 15:30:14.538634762 +0100
@@ -6307,7 +6307,7 @@ pass_expand::execute (function *fun)
   /* Free stuff we no longer need after GIMPLE optimizations.  */
   free_dominance_info (CDI_DOMINATORS);
   free_dominance_info (CDI_POST_DOMINATORS);
-  delete_tree_cfg_annotations ();
+  delete_tree_cfg_annotations (fun);
 
   timevar_push (TV_OUT_OF_SSA);
   finish_out_of_ssa (&SA);
@@ -6321,7 +6321,7 @@ pass_expand::execute (function *fun)
   /* Expansion is used by optimization passes too, set maybe_hot_insn_p
      conservatively to true until they are all profile aware.  */
   delete lab_rtx_for_bb;
-  free_histograms ();
+  free_histograms (fun);
 
   construct_exit_block ();
   insn_locations_finalize ();
Index: trunk/gcc/cfgloop.c
===================================================================
--- trunk.orig/gcc/cfgloop.c	2015-10-26 15:27:42.150921714 +0100
+++ trunk/gcc/cfgloop.c	2015-10-26 15:30:14.539634773 +0100
@@ -1114,12 +1114,12 @@ dump_recorded_exits (FILE *file)
 /* Releases lists of loop exits.  */
 
 void
-release_recorded_exits (void)
+release_recorded_exits (function *fn)
 {
-  gcc_assert (loops_state_satisfies_p (LOOPS_HAVE_RECORDED_EXITS));
-  current_loops->exits->empty ();
-  current_loops->exits = NULL;
-  loops_state_clear (LOOPS_HAVE_RECORDED_EXITS);
+  gcc_assert (loops_state_satisfies_p (fn, LOOPS_HAVE_RECORDED_EXITS));
+  loops_for_fn (fn)->exits->empty ();
+  loops_for_fn (fn)->exits = NULL;
+  loops_state_clear (fn, LOOPS_HAVE_RECORDED_EXITS);
 }
 
 /* Returns the list of the exit edges of a LOOP.  */
Index: trunk/gcc/cfgloop.h
===================================================================
--- trunk.orig/gcc/cfgloop.h	2015-10-26 15:27:42.150921714 +0100
+++ trunk/gcc/cfgloop.h	2015-10-26 15:42:25.975849039 +0100
@@ -264,7 +264,7 @@ extern void flow_loop_free (struct loop
 int flow_loop_nodes_find (basic_block, struct loop *);
 unsigned fix_loop_structure (bitmap changed_bbs);
 bool mark_irreducible_loops (void);
-void release_recorded_exits (void);
+void release_recorded_exits (function *);
 void record_loop_exits (void);
 void rescan_loop_exit (edge, bool, bool);
 
@@ -492,27 +492,45 @@ number_of_loops (struct function *fn)
    described by FLAGS.  */
 
 static inline bool
+loops_state_satisfies_p (function *fn, unsigned flags)
+{
+  return (loops_for_fn (fn)->state & flags) == flags;
+}
+
+static inline bool
 loops_state_satisfies_p (unsigned flags)
 {
-  return (current_loops->state & flags) == flags;
+  return loops_state_satisfies_p (cfun, flags);
 }
 
 /* Sets FLAGS to the loops state.  */
 
 static inline void
+loops_state_set (function *fn, unsigned flags)
+{
+  loops_for_fn (fn)->state |= flags;
+}
+
+static inline void
 loops_state_set (unsigned flags)
 {
-  current_loops->state |= flags;
+  loops_state_set (cfun, flags);
 }
 
 /* Clears FLAGS from the loops state.  */
 
 static inline void
+loops_state_clear (function *fn, unsigned flags)
+{
+  loops_for_fn (fn)->state &= ~flags;
+}
+
+static inline void
 loops_state_clear (unsigned flags)
 {
   if (!current_loops)
     return;
-  current_loops->state &= ~flags;
+  loops_state_clear (cfun, flags);
 }
 
 /* Loop iterators.  */
@@ -531,11 +549,14 @@ enum li_flags
 
 struct loop_iterator
 {
-  loop_iterator (loop_p *loop, unsigned flags);
+  loop_iterator (function *fn, loop_p *loop, unsigned flags);
   ~loop_iterator ();
 
   inline loop_p next ();
 
+  /* The function we are visiting.  */
+  function *fn;
+
   /* The list of loops to visit.  */
   vec<int> to_visit;
 
@@ -551,7 +572,7 @@ loop_iterator::next ()
   while (this->to_visit.iterate (this->idx, &anum))
     {
       this->idx++;
-      loop_p loop = get_loop (cfun, anum);
+      loop_p loop = get_loop (fn, anum);
       if (loop)
 	return loop;
     }
@@ -560,26 +581,27 @@ loop_iterator::next ()
 }
 
 inline
-loop_iterator::loop_iterator (loop_p *loop, unsigned flags)
+loop_iterator::loop_iterator (function *fn, loop_p *loop, unsigned flags)
 {
   struct loop *aloop;
   unsigned i;
   int mn;
 
   this->idx = 0;
-  if (!current_loops)
+  this->fn = fn;
+  if (!loops_for_fn (fn))
     {
       this->to_visit.create (0);
       *loop = NULL;
       return;
     }
 
-  this->to_visit.create (number_of_loops (cfun));
+  this->to_visit.create (number_of_loops (fn));
   mn = (flags & LI_INCLUDE_ROOT) ? 0 : 1;
 
   if (flags & LI_ONLY_INNERMOST)
     {
-      for (i = 0; vec_safe_iterate (current_loops->larray, i, &aloop); i++)
+      for (i = 0; vec_safe_iterate (loops_for_fn (fn)->larray, i, &aloop); i++)
 	if (aloop != NULL
 	    && aloop->inner == NULL
 	    && aloop->num >= mn)
@@ -588,7 +610,7 @@ loop_iterator::loop_iterator (loop_p *lo
   else if (flags & LI_FROM_INNERMOST)
     {
       /* Push the loops to LI->TO_VISIT in postorder.  */
-      for (aloop = current_loops->tree_root;
+      for (aloop = loops_for_fn (fn)->tree_root;
 	   aloop->inner != NULL;
 	   aloop = aloop->inner)
 	continue;
@@ -614,7 +636,7 @@ loop_iterator::loop_iterator (loop_p *lo
   else
     {
       /* Push the loops to LI->TO_VISIT in preorder.  */
-      aloop = current_loops->tree_root;
+      aloop = loops_for_fn (fn)->tree_root;
       while (1)
 	{
 	  if (aloop->num >= mn)
@@ -643,7 +665,12 @@ loop_iterator::~loop_iterator ()
 }
 
 #define FOR_EACH_LOOP(LOOP, FLAGS) \
-  for (loop_iterator li(&(LOOP), FLAGS); \
+  for (loop_iterator li(cfun, &(LOOP), FLAGS); \
+       (LOOP); \
+       (LOOP) = li.next ())
+
+#define FOR_EACH_LOOP_FN(FN, LOOP, FLAGS) \
+  for (loop_iterator li(fn, &(LOOP), FLAGS); \
        (LOOP); \
        (LOOP) = li.next ())
 
@@ -691,7 +718,12 @@ extern void init_set_costs (void);
 
 /* Loop optimizer initialization.  */
 extern void loop_optimizer_init (unsigned);
-extern void loop_optimizer_finalize (void);
+extern void loop_optimizer_finalize (function *);
+inline void
+loop_optimizer_finalize ()
+{
+  loop_optimizer_finalize (cfun);
+}
 
 /* Optimization passes.  */
 enum
Index: trunk/gcc/cgraph.c
===================================================================
--- trunk.orig/gcc/cgraph.c	2015-10-26 15:27:42.150921714 +0100
+++ trunk/gcc/cgraph.c	2015-10-26 15:30:14.541634795 +0100
@@ -1685,39 +1685,38 @@ cgraph_node::remove_callers (void)
 void
 release_function_body (tree decl)
 {
-  if (DECL_STRUCT_FUNCTION (decl))
+  function *fn = DECL_STRUCT_FUNCTION (decl);
+  if (fn)
     {
-      if (DECL_STRUCT_FUNCTION (decl)->cfg
-	  || DECL_STRUCT_FUNCTION (decl)->gimple_df)
+      if (fn->cfg
+	  || fn->gimple_df)
 	{
-	  push_cfun (DECL_STRUCT_FUNCTION (decl));
-	  if (cfun->cfg
-	      && current_loops)
+	  if (fn->cfg
+	      && loops_for_fn (fn))
 	    {
-	      cfun->curr_properties &= ~PROP_loops;
-	      loop_optimizer_finalize ();
+	      fn->curr_properties &= ~PROP_loops;
+	      loop_optimizer_finalize (fn);
 	    }
-	  if (cfun->gimple_df)
+	  if (fn->gimple_df)
 	    {
-	      delete_tree_ssa ();
-	      delete_tree_cfg_annotations ();
-	      cfun->eh = NULL;
+	      delete_tree_ssa (fn);
+	      delete_tree_cfg_annotations (fn);
+	      fn->eh = NULL;
 	    }
-	  if (cfun->cfg)
+	  if (fn->cfg)
 	    {
-	      gcc_assert (!dom_info_available_p (CDI_DOMINATORS));
-	      gcc_assert (!dom_info_available_p (CDI_POST_DOMINATORS));
-	      clear_edges ();
-	      cfun->cfg = NULL;
+	      gcc_assert (!dom_info_available_p (fn, CDI_DOMINATORS));
+	      gcc_assert (!dom_info_available_p (fn, CDI_POST_DOMINATORS));
+	      clear_edges (fn);
+	      fn->cfg = NULL;
 	    }
-	  if (cfun->value_histograms)
-	    free_histograms ();
-	  pop_cfun ();
+	  if (fn->value_histograms)
+	    free_histograms (fn);
 	}
       gimple_set_body (decl, NULL);
       /* Struct function hangs a lot of data that would leak if we didn't
          removed all pointers to it.   */
-      ggc_free (DECL_STRUCT_FUNCTION (decl));
+      ggc_free (fn);
       DECL_STRUCT_FUNCTION (decl) = NULL;
     }
   DECL_SAVED_TREE (decl) = NULL;
Index: trunk/gcc/final.c
===================================================================
--- trunk.orig/gcc/final.c	2015-10-26 15:27:42.150921714 +0100
+++ trunk/gcc/final.c	2015-10-26 15:30:14.542634807 +0100
@@ -4676,7 +4676,7 @@ rest_of_clean_state (void)
 
   free_bb_for_insn ();
 
-  delete_tree_ssa ();
+  delete_tree_ssa (cfun);
 
   /* We can reduce stack alignment on call site only when we are sure that
      the function body just produced will be actually used in the final
Index: trunk/gcc/graphite.c
===================================================================
--- trunk.orig/gcc/graphite.c	2015-10-26 15:27:42.150921714 +0100
+++ trunk/gcc/graphite.c	2015-10-26 15:30:14.543634818 +0100
@@ -268,7 +268,7 @@ graphite_finalize (bool need_cfg_cleanup
       scev_reset ();
       cleanup_tree_cfg ();
       profile_status_for_fn (cfun) = PROFILE_ABSENT;
-      release_recorded_exits ();
+      release_recorded_exits (cfun);
       tree_estimate_probability ();
     }
 
Index: trunk/gcc/loop-init.c
===================================================================
--- trunk.orig/gcc/loop-init.c	2015-10-26 15:27:42.150921714 +0100
+++ trunk/gcc/loop-init.c	2015-10-26 15:30:14.543634818 +0100
@@ -111,7 +111,7 @@ loop_optimizer_init (unsigned flags)
 
       /* Clear all flags.  */
       if (recorded_exits)
-	release_recorded_exits ();
+	release_recorded_exits (cfun);
       loops_state_clear (~0U);
 
       if (needs_fixup)
@@ -139,43 +139,41 @@ loop_optimizer_init (unsigned flags)
 /* Finalize loop structures.  */
 
 void
-loop_optimizer_finalize (void)
+loop_optimizer_finalize (struct function *fn)
 {
   struct loop *loop;
   basic_block bb;
 
   timevar_push (TV_LOOP_FINI);
 
-  if (loops_state_satisfies_p (LOOPS_HAVE_RECORDED_EXITS))
-    release_recorded_exits ();
+  if (loops_state_satisfies_p (fn, LOOPS_HAVE_RECORDED_EXITS))
+    release_recorded_exits (fn);
 
-  free_numbers_of_iterations_estimates ();
+  free_numbers_of_iterations_estimates (fn);
 
   /* If we should preserve loop structure, do not free it but clear
      flags that advanced properties are there as we are not preserving
      that in full.  */
-  if (cfun->curr_properties & PROP_loops)
+  if (fn->curr_properties & PROP_loops)
     {
-      loops_state_clear (LOOP_CLOSED_SSA
+      loops_state_clear (fn, LOOP_CLOSED_SSA
 			 | LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS
 			 | LOOPS_HAVE_PREHEADERS
 			 | LOOPS_HAVE_SIMPLE_LATCHES
 			 | LOOPS_HAVE_FALLTHRU_PREHEADERS);
-      loops_state_set (LOOPS_MAY_HAVE_MULTIPLE_LATCHES);
+      loops_state_set (fn, LOOPS_MAY_HAVE_MULTIPLE_LATCHES);
       goto loop_fini_done;
     }
 
-  gcc_assert (current_loops != NULL);
-
-  FOR_EACH_LOOP (loop, 0)
+  FOR_EACH_LOOP_FN (fn, loop, 0)
     free_simple_loop_desc (loop);
 
   /* Clean up.  */
-  flow_loops_free (current_loops);
-  ggc_free (current_loops);
-  current_loops = NULL;
+  flow_loops_free (loops_for_fn (fn));
+  ggc_free (loops_for_fn (fn));
+  set_loops_for_fn (fn, NULL);
 
-  FOR_ALL_BB_FN (bb, cfun)
+  FOR_ALL_BB_FN (bb, fn)
     {
       bb->loop_father = NULL;
     }
@@ -215,7 +213,7 @@ fix_loop_structure (bitmap changed_bbs)
 
   if (loops_state_satisfies_p (LOOPS_HAVE_RECORDED_EXITS))
     {
-      release_recorded_exits ();
+      release_recorded_exits (cfun);
       record_exits = LOOPS_HAVE_RECORDED_EXITS;
     }
 
Index: trunk/gcc/tree-cfg.c
===================================================================
--- trunk.orig/gcc/tree-cfg.c	2015-10-26 15:27:42.150921714 +0100
+++ trunk/gcc/tree-cfg.c	2015-10-26 15:30:14.545634840 +0100
@@ -2570,9 +2570,9 @@ stmt_ends_bb_p (gimple *t)
 /* Remove block annotations and other data structures.  */
 
 void
-delete_tree_cfg_annotations (void)
+delete_tree_cfg_annotations (struct function *fn)
 {
-  vec_free (label_to_block_map_for_fn (cfun));
+  vec_free (label_to_block_map_for_fn (fn));
 }
 
 /* Return the virtual phi in BB.  */
Index: trunk/gcc/tree-cfg.h
===================================================================
--- trunk.orig/gcc/tree-cfg.h	2015-10-26 15:27:42.150921714 +0100
+++ trunk/gcc/tree-cfg.h	2015-10-26 15:30:14.545634840 +0100
@@ -57,7 +57,7 @@ extern bool is_ctrl_altering_stmt (gimpl
 extern bool simple_goto_p (gimple *);
 extern bool stmt_ends_bb_p (gimple *);
 extern bool assert_unreachable_fallthru_edge_p (edge);
-extern void delete_tree_cfg_annotations (void);
+extern void delete_tree_cfg_annotations (function *);
 extern gphi *get_virtual_phi (basic_block);
 extern gimple *first_stmt (basic_block);
 extern gimple *last_stmt (basic_block);
Index: trunk/gcc/tree-ssa-copy.c
===================================================================
--- trunk.orig/gcc/tree-ssa-copy.c	2015-10-26 15:27:42.150921714 +0100
+++ trunk/gcc/tree-ssa-copy.c	2015-10-26 15:30:14.545634840 +0100
@@ -561,7 +561,7 @@ fini_copy_prop (void)
   bool changed = substitute_and_fold (get_value, NULL, true);
   if (changed)
     {
-      free_numbers_of_iterations_estimates ();
+      free_numbers_of_iterations_estimates (cfun);
       if (scev_initialized_p ())
 	scev_reset ();
     }
Index: trunk/gcc/tree-ssa-dce.c
===================================================================
--- trunk.orig/gcc/tree-ssa-dce.c	2015-10-26 15:27:42.150921714 +0100
+++ trunk/gcc/tree-ssa-dce.c	2015-10-26 15:30:14.546634852 +0100
@@ -1669,7 +1669,7 @@ perform_tree_ssa_dce (bool aggressive)
 
   if (something_changed)
     {
-      free_numbers_of_iterations_estimates ();
+      free_numbers_of_iterations_estimates (cfun);
       if (scev_initialized_p ())
 	scev_reset ();
       return TODO_update_ssa | TODO_cleanup_cfg;
Index: trunk/gcc/tree-ssa-loop-ivcanon.c
===================================================================
--- trunk.orig/gcc/tree-ssa-loop-ivcanon.c	2015-10-26 15:27:42.150921714 +0100
+++ trunk/gcc/tree-ssa-loop-ivcanon.c	2015-10-26 15:30:14.546634852 +0100
@@ -1160,7 +1160,7 @@ canonicalize_induction_variables (void)
   bool irred_invalidated = false;
   bitmap loop_closed_ssa_invalidated = BITMAP_ALLOC (NULL);
 
-  free_numbers_of_iterations_estimates ();
+  free_numbers_of_iterations_estimates (cfun);
   estimate_numbers_of_iterations ();
 
   FOR_EACH_LOOP (loop, LI_FROM_INNERMOST)
@@ -1348,7 +1348,7 @@ tree_unroll_loops_completely (bool may_i
       if (loops_state_satisfies_p (LOOP_CLOSED_SSA))
 	loop_closed_ssa_invalidated = BITMAP_ALLOC (NULL);
 
-      free_numbers_of_iterations_estimates ();
+      free_numbers_of_iterations_estimates (cfun);
       estimate_numbers_of_iterations ();
 
       changed = tree_unroll_loops_completely_1 (may_increase_size,
@@ -1554,7 +1554,7 @@ pass_complete_unrolli::execute (function
     {
       scev_initialize ();
       ret = tree_unroll_loops_completely (optimize >= 3, false);
-      free_numbers_of_iterations_estimates ();
+      free_numbers_of_iterations_estimates (fun);
       scev_finalize ();
     }
   loop_optimizer_finalize ();
Index: trunk/gcc/tree-ssa-loop-niter.c
===================================================================
--- trunk.orig/gcc/tree-ssa-loop-niter.c	2015-10-26 15:27:42.150921714 +0100
+++ trunk/gcc/tree-ssa-loop-niter.c	2015-10-26 15:30:14.546634852 +0100
@@ -4273,11 +4273,11 @@ free_numbers_of_iterations_estimates_loo
 /* Frees the information on upper bounds on numbers of iterations of loops.  */
 
 void
-free_numbers_of_iterations_estimates (void)
+free_numbers_of_iterations_estimates (function *fn)
 {
   struct loop *loop;
 
-  FOR_EACH_LOOP (loop, 0)
+  FOR_EACH_LOOP_FN (fn, loop, 0)
     {
       free_numbers_of_iterations_estimates_loop (loop);
     }
Index: trunk/gcc/tree-ssa-loop-niter.h
===================================================================
--- trunk.orig/gcc/tree-ssa-loop-niter.h	2015-10-26 15:27:42.150921714 +0100
+++ trunk/gcc/tree-ssa-loop-niter.h	2015-10-26 15:30:14.547634863 +0100
@@ -45,7 +45,7 @@ extern bool nowrap_type_p (tree);
 extern bool scev_probably_wraps_p (tree, tree, gimple *, struct loop *, bool);
 extern void free_loop_control_ivs (struct loop *);
 extern void free_numbers_of_iterations_estimates_loop (struct loop *);
-extern void free_numbers_of_iterations_estimates (void);
+extern void free_numbers_of_iterations_estimates (function *);
 extern void substitute_in_loop_info (struct loop *, tree, tree);
 
 #endif /* GCC_TREE_SSA_LOOP_NITER_H */
Index: trunk/gcc/tree-ssa-loop.c
===================================================================
--- trunk.orig/gcc/tree-ssa-loop.c	2015-10-26 15:27:42.150921714 +0100
+++ trunk/gcc/tree-ssa-loop.c	2015-10-26 15:30:14.547634863 +0100
@@ -426,7 +426,7 @@ make_pass_iv_optimize (gcc::context *ctx
 static unsigned int
 tree_ssa_loop_done (void)
 {
-  free_numbers_of_iterations_estimates ();
+  free_numbers_of_iterations_estimates (cfun);
   scev_finalize ();
   loop_optimizer_finalize ();
   return 0;
Index: trunk/gcc/tree-ssa.c
===================================================================
--- trunk.orig/gcc/tree-ssa.c	2015-10-26 15:27:42.150921714 +0100
+++ trunk/gcc/tree-ssa.c	2015-10-26 15:30:14.547634863 +0100
@@ -1137,25 +1137,22 @@ make_pass_init_datastructures (gcc::cont
 /* Deallocate memory associated with SSA data structures for FNDECL.  */
 
 void
-delete_tree_ssa (void)
+delete_tree_ssa (struct function *fn)
 {
-  fini_ssanames ();
+  fini_ssanames (fn);
 
   /* We no longer maintain the SSA operand cache at this point.  */
-  if (ssa_operands_active (cfun))
-    fini_ssa_operands (cfun);
+  if (ssa_operands_active (fn))
+    fini_ssa_operands (fn);
 
-  cfun->gimple_df->default_defs->empty ();
-  cfun->gimple_df->default_defs = NULL;
-  pt_solution_reset (&cfun->gimple_df->escaped);
-  if (cfun->gimple_df->decls_to_pointers != NULL)
-    delete cfun->gimple_df->decls_to_pointers;
-  cfun->gimple_df->decls_to_pointers = NULL;
-  cfun->gimple_df->modified_noreturn_calls = NULL;
-  cfun->gimple_df = NULL;
-
-  /* We no longer need the edge variable maps.  */
-  redirect_edge_var_map_destroy ();
+  fn->gimple_df->default_defs->empty ();
+  fn->gimple_df->default_defs = NULL;
+  pt_solution_reset (&fn->gimple_df->escaped);
+  if (fn->gimple_df->decls_to_pointers != NULL)
+    delete fn->gimple_df->decls_to_pointers;
+  fn->gimple_df->decls_to_pointers = NULL;
+  fn->gimple_df->modified_noreturn_calls = NULL;
+  fn->gimple_df = NULL;
 }
 
 /* Return true if EXPR is a useless type conversion, otherwise return
Index: trunk/gcc/tree-ssa.h
===================================================================
--- trunk.orig/gcc/tree-ssa.h	2015-10-26 15:27:42.150921714 +0100
+++ trunk/gcc/tree-ssa.h	2015-10-26 15:30:14.547634863 +0100
@@ -45,8 +45,8 @@ extern void insert_debug_temps_for_defs
 extern void reset_debug_uses (gimple *);
 extern void release_defs_bitset (bitmap toremove);
 extern void verify_ssa (bool, bool);
-extern void init_tree_ssa (struct function *);
-extern void delete_tree_ssa (void);
+extern void init_tree_ssa (function *);
+extern void delete_tree_ssa (function *);
 extern bool tree_ssa_useless_type_conversion (tree);
 extern tree tree_ssa_strip_useless_type_conversions (tree);
 
Index: trunk/gcc/tree-ssanames.c
===================================================================
--- trunk.orig/gcc/tree-ssanames.c	2015-10-26 15:27:42.150921714 +0100
+++ trunk/gcc/tree-ssanames.c	2015-10-26 15:30:14.547634863 +0100
@@ -103,11 +103,11 @@ init_ssanames (struct function *fn, int
 /* Finalize management of SSA_NAMEs.  */
 
 void
-fini_ssanames (void)
+fini_ssanames (struct function *fn)
 {
-  vec_free (SSANAMES (cfun));
-  vec_free (FREE_SSANAMES (cfun));
-  vec_free (FREE_SSANAMES_QUEUE (cfun));
+  vec_free (SSANAMES (fn));
+  vec_free (FREE_SSANAMES (fn));
+  vec_free (FREE_SSANAMES_QUEUE (fn));
 }
 
 /* Dump some simple statistics regarding the re-use of SSA_NAME nodes.  */
Index: trunk/gcc/tree-ssanames.h
===================================================================
--- trunk.orig/gcc/tree-ssanames.h	2015-10-26 15:27:42.150921714 +0100
+++ trunk/gcc/tree-ssanames.h	2015-10-26 15:30:14.547634863 +0100
@@ -76,7 +76,7 @@ extern enum value_range_type get_range_i
 extern void set_nonzero_bits (tree, const wide_int_ref &);
 extern wide_int get_nonzero_bits (const_tree);
 extern void init_ssanames (struct function *, int);
-extern void fini_ssanames (void);
+extern void fini_ssanames (struct function *);
 extern void ssanames_print_statistics (void);
 extern tree make_ssa_name_fn (struct function *, tree, gimple *);
 extern void release_ssa_name_fn (struct function *, tree);
Index: trunk/gcc/tree-vrp.c
===================================================================
--- trunk.orig/gcc/tree-vrp.c	2015-10-26 15:27:42.150921714 +0100
+++ trunk/gcc/tree-vrp.c	2015-10-26 15:30:14.549634886 +0100
@@ -10281,7 +10281,7 @@ execute_vrp (void)
   ssa_propagate (vrp_visit_stmt, vrp_visit_phi_node);
   vrp_finalize ();
 
-  free_numbers_of_iterations_estimates ();
+  free_numbers_of_iterations_estimates (cfun);
 
   /* ASSERT_EXPRs must be removed before finalizing jump threads
      as finalizing jump threads calls the CFG cleanup code which
Index: trunk/gcc/value-prof.c
===================================================================
--- trunk.orig/gcc/value-prof.c	2015-10-26 15:27:42.150921714 +0100
+++ trunk/gcc/value-prof.c	2015-10-26 15:30:14.549634886 +0100
@@ -603,13 +603,13 @@ free_hist (void **slot, void *data ATTRI
 }
 
 void
-free_histograms (void)
+free_histograms (struct function *fn)
 {
-  if (VALUE_HISTOGRAMS (cfun))
+  if (VALUE_HISTOGRAMS (fn))
     {
-      htab_traverse (VALUE_HISTOGRAMS (cfun), free_hist, NULL);
-      htab_delete (VALUE_HISTOGRAMS (cfun));
-      VALUE_HISTOGRAMS (cfun) = NULL;
+      htab_traverse (VALUE_HISTOGRAMS (fn), free_hist, NULL);
+      htab_delete (VALUE_HISTOGRAMS (fn));
+      VALUE_HISTOGRAMS (fn) = NULL;
     }
 }
 
Index: trunk/gcc/value-prof.h
===================================================================
--- trunk.orig/gcc/value-prof.h	2015-10-26 15:27:42.150921714 +0100
+++ trunk/gcc/value-prof.h	2015-10-26 15:30:14.549634886 +0100
@@ -90,7 +90,7 @@ void gimple_duplicate_stmt_histograms (s
 				       struct function *, gimple *);
 void gimple_move_stmt_histograms (struct function *, gimple *, gimple *);
 void verify_histograms (void);
-void free_histograms (void);
+void free_histograms (function *);
 void stringop_block_profile (gimple *, unsigned int *, HOST_WIDE_INT *);
 gcall *gimple_ic (gcall *, struct cgraph_node *, int, gcov_type,
 		  gcov_type);
