[PATCH 5/6] pass current function to opt_pass::gate ()

tsaunders@mozilla.com tsaunders@mozilla.com
Thu Apr 17 08:38:00 GMT 2014


From: Trevor Saunders <tsaunders@mozilla.com>

Hi,

 This gets rid of usage of cfun, and a bunch of useless functions.

bootstrap + regtest passed on x86_64-unknown-linux-gnu, ok?

Trev

2014-03-19  Trevor Saunders  <tsaunders@mozilla.com>

gcc/
	* passes.c (opt_pass::gate): Take function * argument.
	(gate_all_early_local_passes): Merge into
	(early_local_passes::gate): this.
	(gate_all_early_optimizations): Merge into
	(all_early_optimizations::gate): this.
	(gate_all_optimizations): Mege into
	(all_optimizations::gate): this.
	(gate_all_optimizations_g): Merge into
	(all_optimizations_g::gate): this.
	(gate_rest_of_compilation): Mege into
	(rest_of_compilation::gate): this.
	(gate_postreload): Merge into
	(postreload::gate): this.
	(dump_one_pass): Pass cfun to the pass's gate method.
	(execute_ipa_summary_passes): Likewise.
	(execute_one_pass): Likewise.
	(ipa_write_summaries_2): Likewise.
	(ipa_write_optimization_summaries_1): Likewise.
	(ipa_read_summaries_1): Likewise.
	(ipa_read_optimization_summaries_1): Likewise.
	(execute_ipa_stmt_fixups): Likewise.
	* tree-pass.h (opt_pass::gate): Add function * argument.
	* asan.c, auto-inc-dec.c, bb-reorder.c, bt-load.c,
	combine-stack-adj.c, combine.c, compare-elim.c,
	config/epiphany/resolve-sw-modes.c, config/i386/i386.c,
	config/rl78/rl78.c, config/sh/sh_optimize_sett_clrt.cc,
	config/sh/sh_treg_combine.cc, config/sparc/sparc.c, cprop.c, cse.c,
	dce.c, df-core.c, dse.c, dwarf2cfi.c, except.c,  fwprop.c, gcse.c,
	gimple-ssa-isolate-paths.c, gimple-ssa-strength-reduction.c,
	graphite.c, ifcvt.c, init-regs.c, ipa-cp.c, ipa-devirt.c,
	ipa-profile.c, ipa-pure-const.c, ipa-reference.c, ipa-split.c, ipa.c,
	loop-init.c, lower-subreg.c, mode-switching.c, modulo-sched.c,
	omp-low.c, postreload-gcse.c, postreload.c, predict.c, recog.c, ree.c,
	reg-stack.c, regcprop.c, regrename.c, reorg.c, sched-rgn.c,
	store-motion.c, tracer.c, trans-mem.c, tree-call-cdce.c, tree-cfg.c,
	tree-cfgcleanup.c, tree-complex.c, tree-eh.c, tree-emutls.c,
	tree-if-conv.c, tree-into-ssa.c, tree-loop-distribution.c,
	tree-nrv.c, tree-parloops.c, tree-predcom.c, tree-profile.c,
	tree-sra.c, tree-ssa-ccp.c, tree-ssa-copy.c, tree-ssa-copyrename.c,
	tree-ssa-dce.c, tree-ssa-dom.c, tree-ssa-dse.c, tree-ssa-forwprop.c,
	tree-ssa-ifcombine.c, tree-ssa-loop-ch.c, tree-ssa-loop-im.c,
	tree-ssa-loop-ivcanon.c, tree-ssa-loop-prefetch.c,
	tree-ssa-loop-unswitch.c, tree-ssa-loop.c, tree-ssa-math-opts.c,
	tree-ssa-phiopt.c, tree-ssa-phiprop.c, tree-ssa-pre.c,
	tree-ssa-reassoc.c, tree-ssa-sink.c, tree-ssa-strlen.c,
	tree-ssa-structalias.c, tree-ssa-uncprop.c, tree-ssa-uninit.c,
	tree-ssa.c, tree-stdarg.c, tree-switch-conversion.c, tree-tailcall.c,
	tree-vect-generic.c, tree-vectorizer.c, tree-vrp.c, tsan.c, ubsan.c,
	var-tracking.c, vtable-verify.c, web.c: Adjust.

gcc/testsuite/
	* g++.dg/plugin/dumb_plugin.c, g++.dg/plugin/selfasign.c,
	gcc.dg/plugin/one_time_plugin.c, gcc.dg/plugin/selfasign.c: Adjust.



diff --git a/gcc/asan.c b/gcc/asan.c
index e26ce41..3fe50ef 100644
--- a/gcc/asan.c
+++ b/gcc/asan.c
@@ -2504,7 +2504,7 @@ public:
 
   /* opt_pass methods: */
   opt_pass * clone () { return new pass_asan (m_ctxt); }
-  bool gate () { return gate_asan (); }
+  virtual bool gate (function *) { return gate_asan (); }
   unsigned int execute () { return asan_instrument (); }
 
 }; // class pass_asan
@@ -2517,12 +2517,6 @@ make_pass_asan (gcc::context *ctxt)
   return new pass_asan (ctxt);
 }
 
-static bool
-gate_asan_O0 (void)
-{
-  return !optimize && gate_asan ();
-}
-
 namespace {
 
 const pass_data pass_data_asan_O0 =
@@ -2548,7 +2542,7 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_asan_O0 (); }
+  virtual bool gate (function *) { return !optimize && gate_asan (); }
   unsigned int execute () { return asan_instrument (); }
 
 }; // class pass_asan_O0
@@ -2599,12 +2593,6 @@ execute_sanopt (void)
   return 0;
 }
 
-static bool
-gate_sanopt (void)
-{
-  return flag_sanitize;
-}
-
 namespace {
 
 const pass_data pass_data_sanopt =
@@ -2630,7 +2618,7 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_sanopt (); }
+  virtual bool gate (function *) { return flag_sanitize; }
   unsigned int execute () { return execute_sanopt (); }
 
 }; // class pass_sanopt
diff --git a/gcc/auto-inc-dec.c b/gcc/auto-inc-dec.c
index 4346e85..e1485a3 100644
--- a/gcc/auto-inc-dec.c
+++ b/gcc/auto-inc-dec.c
@@ -1495,17 +1495,6 @@ rest_of_handle_auto_inc_dec (void)
 
 /* Discover auto-inc auto-dec instructions.  */
 
-static bool
-gate_auto_inc_dec (void)
-{
-#ifdef AUTO_INC_DEC
-  return (optimize > 0 && flag_auto_inc_dec);
-#else
-  return false;
-#endif
-}
-
-
 namespace {
 
 const pass_data pass_data_inc_dec =
@@ -1530,7 +1519,16 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_auto_inc_dec (); }
+  virtual bool gate (function *)
+    {
+#ifdef AUTO_INC_DEC
+      return (optimize > 0 && flag_auto_inc_dec);
+#else
+      return false;
+#endif
+    }
+
+
   unsigned int execute () { return rest_of_handle_auto_inc_dec (); }
 
 }; // class pass_inc_dec
diff --git a/gcc/bb-reorder.c b/gcc/bb-reorder.c
index 6ac0242..57103bd 100644
--- a/gcc/bb-reorder.c
+++ b/gcc/bb-reorder.c
@@ -2302,15 +2302,6 @@ insert_section_boundary_note (void)
     }
 }
 
-static bool
-gate_handle_reorder_blocks (void)
-{
-  if (targetm.cannot_modify_jumps_p ())
-    return false;
-  return (optimize > 0
-	  && (flag_reorder_blocks || flag_reorder_blocks_and_partition));
-}
-
 static unsigned int
 rest_of_handle_reorder_blocks (void)
 {
@@ -2355,7 +2346,14 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_handle_reorder_blocks (); }
+  virtual bool gate (function *)
+    {
+      if (targetm.cannot_modify_jumps_p ())
+	return false;
+      return (optimize > 0
+	      && (flag_reorder_blocks || flag_reorder_blocks_and_partition));
+    }
+
   unsigned int execute () { return rest_of_handle_reorder_blocks (); }
 
 }; // class pass_reorder_blocks
@@ -2374,16 +2372,6 @@ make_pass_reorder_blocks (gcc::context *ctxt)
    which can seriously pessimize code with many computed jumps in the source
    code, such as interpreters.  See e.g. PR15242.  */
 
-static bool
-gate_duplicate_computed_gotos (void)
-{
-  if (targetm.cannot_modify_jumps_p ())
-    return false;
-  return (optimize > 0
-	  && flag_expensive_optimizations
-	  && ! optimize_function_for_size_p (cfun));
-}
-
 
 static unsigned int
 duplicate_computed_gotos (void)
@@ -2527,11 +2515,21 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_duplicate_computed_gotos (); }
+  virtual bool gate (function *);
   unsigned int execute () { return duplicate_computed_gotos (); }
 
 }; // class pass_duplicate_computed_gotos
 
+bool
+pass_duplicate_computed_gotos::gate (function *fun)
+{
+  if (targetm.cannot_modify_jumps_p ())
+    return false;
+  return (optimize > 0
+	  && flag_expensive_optimizations
+	  && ! optimize_function_for_size_p (fun));
+}
+
 } // anon namespace
 
 rtl_opt_pass *
@@ -2540,22 +2538,6 @@ make_pass_duplicate_computed_gotos (gcc::context *ctxt)
   return new pass_duplicate_computed_gotos (ctxt);
 }
 
-static bool
-gate_handle_partition_blocks (void)
-{
-  /* The optimization to partition hot/cold basic blocks into separate
-     sections of the .o file does not work well with linkonce or with
-     user defined section attributes.  Don't call it if either case
-     arises.  */
-  return (flag_reorder_blocks_and_partition
-          && optimize
-	  /* See gate_handle_reorder_blocks.  We should not partition if
-	     we are going to omit the reordering.  */
-	  && optimize_function_for_speed_p (cfun)
-	  && !DECL_ONE_ONLY (current_function_decl)
-	  && !user_defined_section_attribute);
-}
-
 /* This function is the main 'entrance' for the optimization that
    partitions hot and cold basic blocks into separate sections of the
    .o file (to improve performance and cache locality).  Ideally it
@@ -2750,11 +2732,27 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_handle_partition_blocks (); }
+  virtual bool gate (function *);
   unsigned int execute () { return partition_hot_cold_basic_blocks (); }
 
 }; // class pass_partition_blocks
 
+bool
+pass_partition_blocks::gate (function *fun)
+{
+  /* The optimization to partition hot/cold basic blocks into separate
+     sections of the .o file does not work well with linkonce or with
+     user defined section attributes.  Don't call it if either case
+     arises.  */
+  return (flag_reorder_blocks_and_partition
+	  && optimize
+	  /* See gate_handle_reorder_blocks.  We should not partition if
+	     we are going to omit the reordering.  */
+	  && optimize_function_for_speed_p (fun)
+	  && !DECL_ONE_ONLY (current_function_decl)
+	  && !user_defined_section_attribute);
+}
+
 } // anon namespace
 
 rtl_opt_pass *
diff --git a/gcc/bt-load.c b/gcc/bt-load.c
index d44917f..fc2aea7 100644
--- a/gcc/bt-load.c
+++ b/gcc/bt-load.c
@@ -1494,12 +1494,6 @@ branch_target_load_optimize (bool after_prologue_epilogue_gen)
     }
 }
 
-static bool
-gate_handle_branch_target_load_optimize1 (void)
-{
-  return flag_branch_target_load_optimize;
-}
-
 
 static unsigned int
 rest_of_handle_branch_target_load_optimize1 (void)
@@ -1532,7 +1526,7 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_handle_branch_target_load_optimize1 (); }
+  virtual bool gate (function *) { return flag_branch_target_load_optimize; }
   unsigned int execute () {
     return rest_of_handle_branch_target_load_optimize1 ();
   }
@@ -1547,12 +1541,6 @@ make_pass_branch_target_load_optimize1 (gcc::context *ctxt)
   return new pass_branch_target_load_optimize1 (ctxt);
 }
 
-static bool
-gate_handle_branch_target_load_optimize2 (void)
-{
-  return (optimize > 0 && flag_branch_target_load_optimize2);
-}
-
 
 static unsigned int
 rest_of_handle_branch_target_load_optimize2 (void)
@@ -1600,7 +1588,11 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_handle_branch_target_load_optimize2 (); }
+  virtual bool gate (function *)
+    {
+      return (optimize > 0 && flag_branch_target_load_optimize2);
+    }
+
   unsigned int execute () {
     return rest_of_handle_branch_target_load_optimize2 ();
   }
diff --git a/gcc/combine-stack-adj.c b/gcc/combine-stack-adj.c
index ec22ab3..37fc7a5 100644
--- a/gcc/combine-stack-adj.c
+++ b/gcc/combine-stack-adj.c
@@ -619,21 +619,6 @@ combine_stack_adjustments_for_block (basic_block bb)
     free_csa_reflist (reflist);
 }
 
-
-static bool
-gate_handle_stack_adjustments (void)
-{
-  /* This is kind of a heuristic.  We need to run combine_stack_adjustments
-     even for machines with possibly nonzero TARGET_RETURN_POPS_ARGS
-     and ACCUMULATE_OUTGOING_ARGS.  We expect that only ports having
-     push instructions will have popping returns.  */
-#ifndef PUSH_ROUNDING
-  if (ACCUMULATE_OUTGOING_ARGS)
-    return false;
-#endif
-  return flag_combine_stack_adjustments;
-}
-
 static unsigned int
 rest_of_handle_stack_adjustments (void)
 {
@@ -667,11 +652,25 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_handle_stack_adjustments (); }
+  virtual bool gate (function *);
   unsigned int execute () { return rest_of_handle_stack_adjustments (); }
 
 }; // class pass_stack_adjustments
 
+bool
+pass_stack_adjustments::gate (function *)
+{
+  /* This is kind of a heuristic.  We need to run combine_stack_adjustments
+     even for machines with possibly nonzero TARGET_RETURN_POPS_ARGS
+     and ACCUMULATE_OUTGOING_ARGS.  We expect that only ports having
+     push instructions will have popping returns.  */
+#ifndef PUSH_ROUNDING
+  if (ACCUMULATE_OUTGOING_ARGS)
+    return false;
+#endif
+  return flag_combine_stack_adjustments;
+}
+
 } // anon namespace
 
 rtl_opt_pass *
diff --git a/gcc/combine.c b/gcc/combine.c
index 63933c0..1b1e33c 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -13854,12 +13854,6 @@ dump_combine_total_stats (FILE *file)
      total_attempts, total_merges, total_extras, total_successes);
 }
 
-static bool
-gate_handle_combine (void)
-{
-  return (optimize > 0);
-}
-
 /* Try combining insns through substitution.  */
 static unsigned int
 rest_of_handle_combine (void)
@@ -13914,7 +13908,7 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_handle_combine (); }
+  virtual bool gate (function *) { return (optimize > 0); }
   unsigned int execute () { return rest_of_handle_combine (); }
 
 }; // class pass_combine
diff --git a/gcc/compare-elim.c b/gcc/compare-elim.c
index e66b1c6..9cddb7a 100644
--- a/gcc/compare-elim.c
+++ b/gcc/compare-elim.c
@@ -643,15 +643,6 @@ execute_compare_elim_after_reload (void)
   return 0;
 }
 
-static bool
-gate_compare_elim_after_reload (void)
-{
-  /* Setting this target hook value is how a backend indicates the need.  */
-  if (targetm.flags_regnum == INVALID_REGNUM)
-    return false;
-  return flag_compare_elim_after_reload;
-}
-
 namespace {
 
 const pass_data pass_data_compare_elim_after_reload =
@@ -677,7 +668,14 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_compare_elim_after_reload (); }
+  virtual bool gate (function *)
+    {
+      /* Setting this target hook value is how a backend indicates the need.  */
+      if (targetm.flags_regnum == INVALID_REGNUM)
+	return false;
+      return flag_compare_elim_after_reload;
+    }
+
   unsigned int execute () { return execute_compare_elim_after_reload (); }
 
 }; // class pass_compare_elim_after_reload
diff --git a/gcc/config/epiphany/resolve-sw-modes.c b/gcc/config/epiphany/resolve-sw-modes.c
index 486330c..31928fd 100644
--- a/gcc/config/epiphany/resolve-sw-modes.c
+++ b/gcc/config/epiphany/resolve-sw-modes.c
@@ -45,12 +45,6 @@ along with GCC; see the file COPYING3.  If not see
    insert new mode setting insns on the edges where the other mode
    becomes unambigous.  */
 
-static bool
-gate_resolve_sw_modes (void)
-{
-  return optimize;
-}
-
 static unsigned
 resolve_sw_modes (void)
 {
@@ -185,7 +179,7 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_resolve_sw_modes (); }
+  virtual bool gate (function *) { return optimize; }
   unsigned int execute () { return resolve_sw_modes (); }
 
 }; // class pass_resolve_sw_modes
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 6dd1bbe..8cfdaf6 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -2493,12 +2493,6 @@ static const struct ptt processor_target_table[PROCESSOR_max] =
   {"btver2", &btver2_cost, 16, 10, 16, 7, 11}
 };
 
-static bool
-gate_insert_vzeroupper (void)
-{
-  return TARGET_AVX && !TARGET_AVX512F && TARGET_VZEROUPPER;
-}
-
 static unsigned int
 rest_of_handle_insert_vzeroupper (void)
 {
@@ -2542,7 +2536,11 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_insert_vzeroupper (); }
+  virtual bool gate (function *)
+    {
+      return TARGET_AVX && !TARGET_AVX512F && TARGET_VZEROUPPER;
+    }
+
   unsigned int execute () { return rest_of_handle_insert_vzeroupper (); }
 
 }; // class pass_insert_vzeroupper
diff --git a/gcc/config/rl78/rl78.c b/gcc/config/rl78/rl78.c
index 88b030f..988e1cd 100644
--- a/gcc/config/rl78/rl78.c
+++ b/gcc/config/rl78/rl78.c
@@ -117,13 +117,6 @@ rl78_init_machine_status (void)
   return m;
 }
 
-/* Returns whether to run the devirtualization pass.  */
-static bool
-devirt_gate (void)
-{
-  return true;
-}
-
 /* Runs the devirtualization pass.  */
 static unsigned int
 devirt_pass (void)
@@ -160,7 +153,6 @@ public:
   }
 
   /* opt_pass methods: */
-  bool gate () { return devirt_gate (); }
   unsigned int execute () { return devirt_pass (); }
 };
 
@@ -243,7 +235,6 @@ public:
   }
 
   /* opt_pass methods: */
-  bool gate () { return devirt_gate (); }
   unsigned int execute () { return move_elim_pass (); }
 };
 
diff --git a/gcc/config/sh/sh_optimize_sett_clrt.cc b/gcc/config/sh/sh_optimize_sett_clrt.cc
index 85cb6a1..5b1afcd 100644
--- a/gcc/config/sh/sh_optimize_sett_clrt.cc
+++ b/gcc/config/sh/sh_optimize_sett_clrt.cc
@@ -79,7 +79,7 @@ class sh_optimize_sett_clrt : public rtl_opt_pass
 public:
   sh_optimize_sett_clrt (gcc::context* ctx, const char* name);
   virtual ~sh_optimize_sett_clrt (void);
-  virtual bool gate (void);
+  virtual bool gate (function *);
   virtual unsigned int execute (void);
 
 private:
@@ -161,7 +161,7 @@ sh_optimize_sett_clrt::~sh_optimize_sett_clrt (void)
 }
 
 bool
-sh_optimize_sett_clrt::gate (void)
+sh_optimize_sett_clrt::gate (function *)
 {
   return optimize > 0;
 }
diff --git a/gcc/config/sh/sh_treg_combine.cc b/gcc/config/sh/sh_treg_combine.cc
index 1285ba2..57eddd2 100644
--- a/gcc/config/sh/sh_treg_combine.cc
+++ b/gcc/config/sh/sh_treg_combine.cc
@@ -424,7 +424,7 @@ class sh_treg_combine : public rtl_opt_pass
 public:
   sh_treg_combine (gcc::context* ctx, bool split_insns, const char* name);
   virtual ~sh_treg_combine (void);
-  virtual bool gate (void);
+  virtual bool gate (function *);
   virtual unsigned int execute (void);
 
 private:
@@ -1435,7 +1435,7 @@ sh_treg_combine::try_optimize_cbranch (rtx insn)
 }
 
 bool
-sh_treg_combine::gate (void)
+sh_treg_combine::gate (function *)
 {
   return optimize > 0;
 }
diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c
index a63e813..5578cb8 100644
--- a/gcc/config/sparc/sparc.c
+++ b/gcc/config/sparc/sparc.c
@@ -871,13 +871,6 @@ mem_ref (rtx x)
    pass runs as late as possible.  The pass is inserted in the pass pipeline
    at the end of sparc_option_override.  */
 
-static bool
-sparc_gate_work_around_errata (void)
-{
-  /* The only errata we handle are those of the AT697F and UT699.  */
-  return sparc_fix_at697f != 0 || sparc_fix_ut699 != 0;
-}
-
 static unsigned int
 sparc_do_work_around_errata (void)
 {
@@ -1146,7 +1139,12 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return sparc_gate_work_around_errata (); }
+  virtual bool gate (function *)
+    {
+      /* The only errata we handle are those of the AT697F and UT699.  */
+      return sparc_fix_at697f != 0 || sparc_fix_ut699 != 0;
+    }
+
   unsigned int execute () { return sparc_do_work_around_errata (); }
 
 }; // class pass_work_around_errata
diff --git a/gcc/cprop.c b/gcc/cprop.c
index f22cde7..9802b8a 100644
--- a/gcc/cprop.c
+++ b/gcc/cprop.c
@@ -1896,14 +1896,6 @@ one_cprop_pass (void)
    setjmp.
    FIXME: Should just handle setjmp via REG_SETJMP notes.  */
 
-static bool
-gate_rtl_cprop (void)
-{
-  return optimize > 0 && flag_gcse
-    && !cfun->calls_setjmp
-    && dbg_cnt (cprop);
-}
-
 static unsigned int
 execute_rtl_cprop (void)
 {
@@ -1944,7 +1936,13 @@ public:
 
   /* opt_pass methods: */
   opt_pass * clone () { return new pass_rtl_cprop (m_ctxt); }
-  bool gate () { return gate_rtl_cprop (); }
+  virtual bool gate (function *fun)
+    {
+      return optimize > 0 && flag_gcse
+	&& !fun->calls_setjmp
+	&& dbg_cnt (cprop);
+    }
+
   unsigned int execute () { return execute_rtl_cprop (); }
 
 }; // class pass_rtl_cprop
diff --git a/gcc/cse.c b/gcc/cse.c
index 6edea01..60ec9a9 100644
--- a/gcc/cse.c
+++ b/gcc/cse.c
@@ -7457,12 +7457,6 @@ cse_condition_code_reg (void)
 /* Perform common subexpression elimination.  Nonzero value from
    `cse_main' means that jumps were simplified and some code may now
    be unreachable, so do jump optimization again.  */
-static bool
-gate_handle_cse (void)
-{
-  return optimize > 0;
-}
-
 static unsigned int
 rest_of_handle_cse (void)
 {
@@ -7515,7 +7509,7 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_handle_cse (); }
+  virtual bool gate (function *) { return optimize > 0; }
   unsigned int execute () { return rest_of_handle_cse (); }
 
 }; // class pass_cse
@@ -7529,12 +7523,6 @@ make_pass_cse (gcc::context *ctxt)
 }
 
 
-static bool
-gate_handle_cse2 (void)
-{
-  return optimize > 0 && flag_rerun_cse_after_loop;
-}
-
 /* Run second CSE pass after loop optimizations.  */
 static unsigned int
 rest_of_handle_cse2 (void)
@@ -7594,7 +7582,11 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_handle_cse2 (); }
+  virtual bool gate (function *)
+    {
+      return optimize > 0 && flag_rerun_cse_after_loop;
+    }
+
   unsigned int execute () { return rest_of_handle_cse2 (); }
 
 }; // class pass_cse2
@@ -7607,12 +7599,6 @@ make_pass_cse2 (gcc::context *ctxt)
   return new pass_cse2 (ctxt);
 }
 
-static bool
-gate_handle_cse_after_global_opts (void)
-{
-  return optimize > 0 && flag_rerun_cse_after_global_opts;
-}
-
 /* Run second CSE pass after loop optimizations.  */
 static unsigned int
 rest_of_handle_cse_after_global_opts (void)
@@ -7671,7 +7657,11 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_handle_cse_after_global_opts (); }
+  virtual bool gate (function *)
+    {
+      return optimize > 0 && flag_rerun_cse_after_global_opts;
+    }
+
   unsigned int execute () {
     return rest_of_handle_cse_after_global_opts ();
   }
diff --git a/gcc/dce.c b/gcc/dce.c
index 33cdefd..1d290e3 100644
--- a/gcc/dce.c
+++ b/gcc/dce.c
@@ -779,13 +779,6 @@ rest_of_handle_ud_dce (void)
 }
 
 
-static bool
-gate_ud_dce (void)
-{
-  return optimize > 1 && flag_dce
-    && dbg_cnt (dce_ud);
-}
-
 namespace {
 
 const pass_data pass_data_ud_rtl_dce =
@@ -810,7 +803,11 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_ud_dce (); }
+  virtual bool gate (function *)
+    {
+      return optimize > 1 && flag_dce && dbg_cnt (dce_ud);
+    }
+
   unsigned int execute () { return rest_of_handle_ud_dce (); }
 
 }; // class pass_ud_rtl_dce
@@ -1211,13 +1208,6 @@ run_fast_dce (void)
 }
 
 
-static bool
-gate_fast_dce (void)
-{
-  return optimize > 0 && flag_dce
-    && dbg_cnt (dce_fast);
-}
-
 namespace {
 
 const pass_data pass_data_fast_rtl_dce =
@@ -1242,7 +1232,11 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_fast_dce (); }
+  virtual bool gate (function *)
+    {
+      return optimize > 0 && flag_dce && dbg_cnt (dce_fast);
+    }
+
   unsigned int execute () { return rest_of_handle_fast_dce (); }
 
 }; // class pass_fast_rtl_dce
diff --git a/gcc/df-core.c b/gcc/df-core.c
index 9909ac3..bd3cb31 100644
--- a/gcc/df-core.c
+++ b/gcc/df-core.c
@@ -740,13 +740,6 @@ rest_of_handle_df_initialize (void)
 }
 
 
-static bool
-gate_opt (void)
-{
-  return optimize > 0;
-}
-
-
 namespace {
 
 const pass_data pass_data_df_initialize_opt =
@@ -771,7 +764,7 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_opt (); }
+  virtual bool gate (function *) { return optimize > 0; }
   unsigned int execute () { return rest_of_handle_df_initialize (); }
 
 }; // class pass_df_initialize_opt
@@ -785,13 +778,6 @@ make_pass_df_initialize_opt (gcc::context *ctxt)
 }
 
 
-static bool
-gate_no_opt (void)
-{
-  return optimize == 0;
-}
-
-
 namespace {
 
 const pass_data pass_data_df_initialize_no_opt =
@@ -816,7 +802,7 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_no_opt (); }
+  virtual bool gate (function *) { return optimize == 0; }
   unsigned int execute () { return rest_of_handle_df_initialize (); }
 
 }; // class pass_df_initialize_no_opt
diff --git a/gcc/dse.c b/gcc/dse.c
index a3a66b1..a80c025 100644
--- a/gcc/dse.c
+++ b/gcc/dse.c
@@ -608,11 +608,6 @@ static bitmap kill_on_calls;
 
 /* The number of bits used in the global bitmaps.  */
 static unsigned int current_position;
-
-
-static bool gate_dse1 (void);
-static bool gate_dse2 (void);
-
 
 /*----------------------------------------------------------------------------
    Zeroth step.
@@ -3712,20 +3707,6 @@ rest_of_handle_dse (void)
   return 0;
 }
 
-static bool
-gate_dse1 (void)
-{
-  return optimize > 0 && flag_dse
-    && dbg_cnt (dse1);
-}
-
-static bool
-gate_dse2 (void)
-{
-  return optimize > 0 && flag_dse
-    && dbg_cnt (dse2);
-}
-
 namespace {
 
 const pass_data pass_data_rtl_dse1 =
@@ -3750,7 +3731,11 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_dse1 (); }
+  virtual bool gate (function *)
+    {
+      return optimize > 0 && flag_dse && dbg_cnt (dse1);
+    }
+
   unsigned int execute () { return rest_of_handle_dse (); }
 
 }; // class pass_rtl_dse1
@@ -3787,7 +3772,11 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_dse2 (); }
+  virtual bool gate (function *)
+    {
+      return optimize > 0 && flag_dse && dbg_cnt (dse2);
+    }
+
   unsigned int execute () { return rest_of_handle_dse (); }
 
 }; // class pass_rtl_dse2
diff --git a/gcc/dwarf2cfi.c b/gcc/dwarf2cfi.c
index d278a27..3749277 100644
--- a/gcc/dwarf2cfi.c
+++ b/gcc/dwarf2cfi.c
@@ -3377,21 +3377,6 @@ dwarf2out_do_cfi_asm (void)
   return true;
 }
 
-static bool
-gate_dwarf2_frame (void)
-{
-#ifndef HAVE_prologue
-  /* Targets which still implement the prologue in assembler text
-     cannot use the generic dwarf2 unwinding.  */
-  return false;
-#endif
-
-  /* ??? What to do for UI_TARGET unwinding?  They might be able to benefit
-     from the optimized shrink-wrapping annotations that we will compute.
-     For now, only produce the CFI notes for dwarf2.  */
-  return dwarf2out_do_frame ();
-}
-
 namespace {
 
 const pass_data pass_data_dwarf2_frame =
@@ -3416,11 +3401,26 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_dwarf2_frame (); }
+  virtual bool gate (function *);
   unsigned int execute () { return execute_dwarf2_frame (); }
 
 }; // class pass_dwarf2_frame
 
+bool
+pass_dwarf2_frame::gate (function *)
+{
+#ifndef HAVE_prologue
+  /* Targets which still implement the prologue in assembler text
+     cannot use the generic dwarf2 unwinding.  */
+  return false;
+#endif
+
+  /* ??? What to do for UI_TARGET unwinding?  They might be able to benefit
+     from the optimized shrink-wrapping annotations that we will compute.
+     For now, only produce the CFI notes for dwarf2.  */
+  return dwarf2out_do_frame ();
+}
+
 } // anon namespace
 
 rtl_opt_pass *
diff --git a/gcc/except.c b/gcc/except.c
index cf3cd5f..2015809 100644
--- a/gcc/except.c
+++ b/gcc/except.c
@@ -2620,17 +2620,6 @@ convert_to_eh_region_ranges (void)
   return 0;
 }
 
-static bool
-gate_convert_to_eh_region_ranges (void)
-{
-  /* Nothing to do for SJLJ exceptions or if no regions created.  */
-  if (cfun->eh->region_tree == NULL)
-    return false;
-  if (targetm_common.except_unwind_info (&global_options) == UI_SJLJ)
-    return false;
-  return true;
-}
-
 namespace {
 
 const pass_data pass_data_convert_to_eh_region_ranges =
@@ -2655,11 +2644,22 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_convert_to_eh_region_ranges (); }
+  virtual bool gate (function *);
   unsigned int execute () { return convert_to_eh_region_ranges (); }
 
 }; // class pass_convert_to_eh_region_ranges
 
+bool
+pass_convert_to_eh_region_ranges::gate (function *)
+{
+  /* Nothing to do for SJLJ exceptions or if no regions created.  */
+  if (cfun->eh->region_tree == NULL)
+    return false;
+  if (targetm_common.except_unwind_info (&global_options) == UI_SJLJ)
+    return false;
+  return true;
+}
+
 } // anon namespace
 
 rtl_opt_pass *
diff --git a/gcc/fwprop.c b/gcc/fwprop.c
index 061d533..c6fa4ee 100644
--- a/gcc/fwprop.c
+++ b/gcc/fwprop.c
@@ -1508,7 +1508,7 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_fwprop (); }
+  virtual bool gate (function *) { return gate_fwprop (); }
   unsigned int execute () { return fwprop (); }
 
 }; // class pass_rtl_fwprop
@@ -1573,7 +1573,7 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_fwprop (); }
+  virtual bool gate (function *) { return gate_fwprop (); }
   unsigned int execute () { return fwprop_addr (); }
 
 }; // class pass_rtl_fwprop_addr
diff --git a/gcc/gcse.c b/gcc/gcse.c
index 6797b08..942ea64 100644
--- a/gcc/gcse.c
+++ b/gcc/gcse.c
@@ -4157,24 +4157,6 @@ is_too_expensive (const char *pass)
   return false;
 }
 
-/* All the passes implemented in this file.  Each pass has its
-   own gate and execute function, and at the end of the file a
-   pass definition for passes.c.
-
-   We do not construct an accurate cfg in functions which call
-   setjmp, so none of these passes runs if the function calls
-   setjmp.
-   FIXME: Should just handle setjmp via REG_SETJMP notes.  */
-
-static bool
-gate_rtl_pre (void)
-{
-  return optimize > 0 && flag_gcse
-    && !cfun->calls_setjmp
-    && optimize_function_for_speed_p (cfun)
-    && dbg_cnt (pre);
-}
-
 static unsigned int
 execute_rtl_pre (void)
 {
@@ -4188,18 +4170,6 @@ execute_rtl_pre (void)
   return 0;
 }
 
-static bool
-gate_rtl_hoist (void)
-{
-  return optimize > 0 && flag_gcse
-    && !cfun->calls_setjmp
-    /* It does not make sense to run code hoisting unless we are optimizing
-       for code size -- it rarely makes programs faster, and can make then
-       bigger if we did PRE (when optimizing for space, we don't run PRE).  */
-    && optimize_function_for_size_p (cfun)
-    && dbg_cnt (hoist);
-}
-
 static unsigned int
 execute_rtl_hoist (void)
 {
@@ -4238,11 +4208,25 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_rtl_pre (); }
+  virtual bool gate (function *);
   unsigned int execute () { return execute_rtl_pre (); }
 
 }; // class pass_rtl_pre
 
+/* We do not construct an accurate cfg in functions which call
+   setjmp, so none of these passes runs if the function calls
+   setjmp.
+   FIXME: Should just handle setjmp via REG_SETJMP notes.  */
+
+bool
+pass_rtl_pre::gate (function *fun)
+{
+  return optimize > 0 && flag_gcse
+    && !fun->calls_setjmp
+    && optimize_function_for_speed_p (fun)
+    && dbg_cnt (pre);
+}
+
 } // anon namespace
 
 rtl_opt_pass *
@@ -4276,11 +4260,23 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_rtl_hoist (); }
+  virtual bool gate (function *);
   unsigned int execute () { return execute_rtl_hoist (); }
 
 }; // class pass_rtl_hoist
 
+bool
+pass_rtl_hoist::gate (function *)
+{
+  return optimize > 0 && flag_gcse
+    && !cfun->calls_setjmp
+    /* It does not make sense to run code hoisting unless we are optimizing
+       for code size -- it rarely makes programs faster, and can make then
+       bigger if we did PRE (when optimizing for space, we don't run PRE).  */
+    && optimize_function_for_size_p (cfun)
+    && dbg_cnt (hoist);
+}
+
 } // anon namespace
 
 rtl_opt_pass *
diff --git a/gcc/gimple-ssa-isolate-paths.c b/gcc/gimple-ssa-isolate-paths.c
index e0ce2ec..ab6185c 100644
--- a/gcc/gimple-ssa-isolate-paths.c
+++ b/gcc/gimple-ssa-isolate-paths.c
@@ -414,15 +414,6 @@ gimple_ssa_isolate_erroneous_paths (void)
   return 0;
 }
 
-static bool
-gate_isolate_erroneous_paths (void)
-{
-  /* If we do not have a suitable builtin function for the trap statement,
-     then do not perform the optimization.  */
-  return (flag_isolate_erroneous_paths_dereference != 0
-	  || flag_isolate_erroneous_paths_attribute != 0);
-}
-
 namespace {
 const pass_data pass_data_isolate_erroneous_paths =
 {
@@ -447,7 +438,14 @@ public:
 
   /* opt_pass methods: */
   opt_pass * clone () { return new pass_isolate_erroneous_paths (m_ctxt); }
-  bool gate () { return gate_isolate_erroneous_paths (); }
+  virtual bool gate (function *)
+    {
+      /* If we do not have a suitable builtin function for the trap statement,
+	 then do not perform the optimization.  */
+      return (flag_isolate_erroneous_paths_dereference != 0
+	      || flag_isolate_erroneous_paths_attribute != 0);
+    }
+
   unsigned int execute () { return gimple_ssa_isolate_erroneous_paths (); }
 
 }; // class pass_isolate_erroneous_paths
diff --git a/gcc/gimple-ssa-strength-reduction.c b/gcc/gimple-ssa-strength-reduction.c
index 8d19031..a8596e0 100644
--- a/gcc/gimple-ssa-strength-reduction.c
+++ b/gcc/gimple-ssa-strength-reduction.c
@@ -3646,12 +3646,6 @@ execute_strength_reduction (void)
   return 0;
 }
 
-static bool
-gate_strength_reduction (void)
-{
-  return flag_tree_slsr;
-}
-
 namespace {
 
 const pass_data pass_data_strength_reduction =
@@ -3676,7 +3670,7 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_strength_reduction (); }
+  virtual bool gate (function *) { return flag_tree_slsr; }
   unsigned int execute () { return execute_strength_reduction (); }
 
 }; // class pass_strength_reduction
diff --git a/gcc/graphite.c b/gcc/graphite.c
index 03a7161..68c9390 100644
--- a/gcc/graphite.c
+++ b/gcc/graphite.c
@@ -374,7 +374,7 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_graphite_transforms (); }
+  virtual bool gate (function *) { return gate_graphite_transforms (); }
 
 }; // class pass_graphite
 
@@ -410,7 +410,7 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_graphite_transforms (); }
+  virtual bool gate (function *) { return gate_graphite_transforms (); }
   unsigned int execute () { return graphite_transforms (); }
 
 }; // class pass_graphite_transforms
diff --git a/gcc/ifcvt.c b/gcc/ifcvt.c
index 5c0843d..657b585 100644
--- a/gcc/ifcvt.c
+++ b/gcc/ifcvt.c
@@ -4512,13 +4512,6 @@ if_convert (bool after_combine)
 #endif
 }
 
-static bool
-gate_handle_if_conversion (void)
-{
-  return (optimize > 0)
-    && dbg_cnt (if_conversion);
-}
-
 /* If-conversion and CFG cleanup.  */
 static unsigned int
 rest_of_handle_if_conversion (void)
@@ -4562,7 +4555,11 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_handle_if_conversion (); }
+  virtual bool gate (function *)
+    {
+      return (optimize > 0) && dbg_cnt (if_conversion);
+    }
+
   unsigned int execute () { return rest_of_handle_if_conversion (); }
 
 }; // class pass_rtl_ifcvt
@@ -4575,13 +4572,6 @@ make_pass_rtl_ifcvt (gcc::context *ctxt)
   return new pass_rtl_ifcvt (ctxt);
 }
 
-static bool
-gate_handle_if_after_combine (void)
-{
-  return optimize > 0 && flag_if_conversion
-    && dbg_cnt (if_after_combine);
-}
-
 
 /* Rerun if-conversion, as combine may have simplified things enough
    to now meet sequence length restrictions.  */
@@ -4616,7 +4606,12 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_handle_if_after_combine (); }
+  virtual bool gate (function *)
+    {
+      return optimize > 0 && flag_if_conversion
+	&& dbg_cnt (if_after_combine);
+    }
+
   unsigned int execute () { return rest_of_handle_if_after_combine (); }
 
 }; // class pass_if_after_combine
@@ -4630,13 +4625,6 @@ make_pass_if_after_combine (gcc::context *ctxt)
 }
 
 
-static bool
-gate_handle_if_after_reload (void)
-{
-  return optimize > 0 && flag_if_conversion2
-    && dbg_cnt (if_after_reload);
-}
-
 static unsigned int
 rest_of_handle_if_after_reload (void)
 {
@@ -4669,7 +4657,12 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_handle_if_after_reload (); }
+  virtual bool gate (function *)
+    {
+      return optimize > 0 && flag_if_conversion2
+	&& dbg_cnt (if_after_reload);
+    }
+
   unsigned int execute () { return rest_of_handle_if_after_reload (); }
 
 }; // class pass_if_after_reload
diff --git a/gcc/init-regs.c b/gcc/init-regs.c
index 265fed7..2025b77 100644
--- a/gcc/init-regs.c
+++ b/gcc/init-regs.c
@@ -125,12 +125,6 @@ initialize_uninitialized_regs (void)
   BITMAP_FREE (already_genned);
 }
 
-static bool
-gate_initialize_regs (void)
-{
-  return optimize > 0;
-}
-
 static unsigned int
 rest_of_handle_initialize_regs (void)
 {
@@ -162,7 +156,7 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_initialize_regs (); }
+  virtual bool gate (function *) { return optimize > 0; }
   unsigned int execute () { return rest_of_handle_initialize_regs (); }
 
 }; // class pass_initialize_regs
diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c
index 1f28b69..ee48fc0 100644
--- a/gcc/ipa-cp.c
+++ b/gcc/ipa-cp.c
@@ -3762,16 +3762,6 @@ ipcp_read_summary (void)
   ipa_prop_read_jump_functions ();
 }
 
-/* Gate for IPCP optimization.  */
-
-static bool
-cgraph_gate_cp (void)
-{
-  /* FIXME: We should remove the optimize check after we ensure we never run
-     IPA passes when not optimizing.  */
-  return flag_ipa_cp && optimize;
-}
-
 namespace {
 
 const pass_data pass_data_ipa_cp =
@@ -3807,7 +3797,13 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return cgraph_gate_cp (); }
+  virtual bool gate (function *)
+    {
+      /* FIXME: We should remove the optimize check after we ensure we never run
+	 IPA passes when not optimizing.  */
+      return flag_ipa_cp && optimize;
+    }
+
   unsigned int execute () { return ipcp_driver (); }
 
 }; // class pass_ipa_cp
diff --git a/gcc/ipa-devirt.c b/gcc/ipa-devirt.c
index 19369c6..3bc6815 100644
--- a/gcc/ipa-devirt.c
+++ b/gcc/ipa-devirt.c
@@ -1911,16 +1911,6 @@ ipa_devirt (void)
   return ndevirtualized ? TODO_remove_functions : 0;
 }
 
-/* Gate for speculative IPA devirtualization optimization.  */
-
-static bool
-gate_ipa_devirt (void)
-{
-  return (flag_devirtualize
-	  && flag_devirtualize_speculatively
-	  && optimize);
-}
-
 namespace {
 
 const pass_data pass_data_ipa_devirt =
@@ -1954,7 +1944,13 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_ipa_devirt (); }
+  virtual bool gate (function *)
+    {
+      return (flag_devirtualize
+	      && flag_devirtualize_speculatively
+	      && optimize);
+    }
+
   unsigned int execute () { return ipa_devirt (); }
 
 }; // class pass_ipa_devirt
diff --git a/gcc/ipa-profile.c b/gcc/ipa-profile.c
index f2a72de..7b58716 100644
--- a/gcc/ipa-profile.c
+++ b/gcc/ipa-profile.c
@@ -711,12 +711,6 @@ ipa_profile (void)
   return 0;
 }
 
-static bool
-gate_ipa_profile (void)
-{
-  return flag_ipa_profile;
-}
-
 namespace {
 
 const pass_data pass_data_ipa_profile =
@@ -750,7 +744,7 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_ipa_profile (); }
+  virtual bool gate (function *) { return flag_ipa_profile; }
   unsigned int execute () { return ipa_profile (); }
 
 }; // class pass_ipa_profile
diff --git a/gcc/ipa-pure-const.c b/gcc/ipa-pure-const.c
index eac3636..eab7633 100644
--- a/gcc/ipa-pure-const.c
+++ b/gcc/ipa-pure-const.c
@@ -1541,7 +1541,7 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_pure_const (); }
+  virtual bool gate (function *) { return gate_pure_const (); }
   unsigned int execute () { return propagate (); }
 
 }; // class pass_ipa_pure_const
@@ -1716,7 +1716,7 @@ public:
 
   /* opt_pass methods: */
   opt_pass * clone () { return new pass_local_pure_const (m_ctxt); }
-  bool gate () { return gate_pure_const (); }
+  virtual bool gate (function *) { return gate_pure_const (); }
   unsigned int execute () { return local_pure_const (); }
 
 }; // class pass_local_pure_const
@@ -1740,12 +1740,6 @@ execute_warn_function_noreturn (void)
   return 0;
 }
 
-static bool
-gate_warn_function_noreturn (void)
-{
-  return warn_suggest_attribute_noreturn;
-}
-
 namespace {
 
 const pass_data pass_data_warn_function_noreturn =
@@ -1770,7 +1764,7 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_warn_function_noreturn (); }
+  virtual bool gate (function *) { return warn_suggest_attribute_noreturn; }
   unsigned int execute () { return execute_warn_function_noreturn (); }
 
 }; // class pass_warn_function_noreturn
diff --git a/gcc/ipa-reference.c b/gcc/ipa-reference.c
index 126948e..51a57ac 100644
--- a/gcc/ipa-reference.c
+++ b/gcc/ipa-reference.c
@@ -1148,14 +1148,6 @@ ipa_reference_read_optimization_summary (void)
     }
 }
 
-static bool
-gate_reference (void)
-{
-  return (flag_ipa_reference
-	  /* Don't bother doing anything if the program has errors.  */
-	  && !seen_error ());
-}
-
 namespace {
 
 const pass_data pass_data_ipa_reference =
@@ -1191,7 +1183,13 @@ public:
     {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_reference (); }
+  virtual bool gate (function *)
+    {
+      return (flag_ipa_reference
+	      /* Don't bother doing anything if the program has errors.  */
+	      && !seen_error ());
+    }
+
   unsigned int execute () { return propagate (); }
 
 }; // class pass_ipa_reference
diff --git a/gcc/ipa-split.c b/gcc/ipa-split.c
index ebb9197..187dc98 100644
--- a/gcc/ipa-split.c
+++ b/gcc/ipa-split.c
@@ -1646,17 +1646,6 @@ execute_split_functions (void)
   return todo;
 }
 
-/* Gate function splitting pass.  When doing profile feedback, we want
-   to execute the pass after profiling is read.  So disable one in 
-   early optimization.  */
-
-static bool
-gate_split_functions (void)
-{
-  return (flag_partial_inlining
-	  && !profile_arc_flag && !flag_branch_probabilities);
-}
-
 namespace {
 
 const pass_data pass_data_split_functions =
@@ -1681,11 +1670,20 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_split_functions (); }
+  virtual bool gate (function *);
   unsigned int execute () { return execute_split_functions (); }
 
 }; // class pass_split_functions
 
+bool
+pass_split_functions::gate (function *)
+{
+  /* When doing profile feedback, we want to execute the pass after profiling
+     is read.  So disable one in early optimization.  */
+  return (flag_partial_inlining
+	  && !profile_arc_flag && !flag_branch_probabilities);
+}
+
 } // anon namespace
 
 gimple_opt_pass *
@@ -1694,17 +1692,6 @@ make_pass_split_functions (gcc::context *ctxt)
   return new pass_split_functions (ctxt);
 }
 
-/* Gate feedback driven function splitting pass.
-   We don't need to split when profiling at all, we are producing
-   lousy code anyway.  */
-
-static bool
-gate_feedback_split_functions (void)
-{
-  return (flag_partial_inlining
-	  && flag_branch_probabilities);
-}
-
 /* Execute function splitting pass.  */
 
 static unsigned int
@@ -1740,11 +1727,20 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_feedback_split_functions (); }
+  virtual bool gate (function *);
   unsigned int execute () { return execute_feedback_split_functions (); }
 
 }; // class pass_feedback_split_functions
 
+bool
+pass_feedback_split_functions::gate (function *)
+{
+  /* We don't need to split when profiling at all, we are producing
+     lousy code anyway.  */
+  return (flag_partial_inlining
+	  && flag_branch_probabilities);
+}
+
 } // anon namespace
 
 gimple_opt_pass *
diff --git a/gcc/ipa.c b/gcc/ipa.c
index 5e06509..7af2584 100644
--- a/gcc/ipa.c
+++ b/gcc/ipa.c
@@ -1272,14 +1272,6 @@ make_pass_ipa_free_inline_summary (gcc::context *ctxt)
   return new pass_ipa_free_inline_summary (ctxt);
 }
 
-/* Do not re-run on ltrans stage.  */
-
-static bool
-gate_whole_program_function_and_variable_visibility (void)
-{
-  return !flag_ltrans;
-}
-
 /* Bring functionss local at LTO time with -fwhole-program.  */
 
 static unsigned int
@@ -1324,9 +1316,12 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () {
-    return gate_whole_program_function_and_variable_visibility ();
-  }
+
+  virtual bool gate (function *)
+    {
+      /* Do not re-run on ltrans stage.  */
+      return !flag_ltrans;
+    }
   unsigned int execute () {
     return whole_program_function_and_variable_visibility ();
   }
@@ -1613,16 +1608,6 @@ ipa_cdtor_merge (void)
   return 0;
 }
 
-/* Perform the pass when we have no ctors/dtors support
-   or at LTO time to merge multiple constructors into single
-   function.  */
-
-static bool
-gate_ipa_cdtor_merge (void)
-{
-  return !targetm.have_ctors_dtors || (optimize && in_lto_p);
-}
-
 namespace {
 
 const pass_data pass_data_ipa_cdtor_merge =
@@ -1656,11 +1641,20 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_ipa_cdtor_merge (); }
+  virtual bool gate (function *);
   unsigned int execute () { return ipa_cdtor_merge (); }
 
 }; // class pass_ipa_cdtor_merge
 
+bool
+pass_ipa_cdtor_merge::gate (function *)
+{
+  /* Perform the pass when we have no ctors/dtors support
+     or at LTO time to merge multiple constructors into single
+     function.  */
+  return !targetm.have_ctors_dtors || (optimize && in_lto_p);
+}
+
 } // anon namespace
 
 ipa_opt_pass_d *
diff --git a/gcc/loop-init.c b/gcc/loop-init.c
index d0bd4ec..6da29d3 100644
--- a/gcc/loop-init.c
+++ b/gcc/loop-init.c
@@ -287,31 +287,8 @@ fix_loop_structure (bitmap changed_bbs)
   return number_of_loops (cfun) - old_nloops;
 }
 
-/* Gate for the RTL loop superpass.  The actual passes are subpasses.
-   See passes.c for more on that.  */
-
-static bool
-gate_handle_loop2 (void)
-{
-  if (optimize > 0
-      && (flag_move_loop_invariants
-	  || flag_unswitch_loops
-	  || flag_peel_loops
-	  || flag_unroll_loops
-#ifdef HAVE_doloop_end
-	  || (flag_branch_on_count_reg && HAVE_doloop_end)
-#endif
-	 ))
-    return true;
-  else
-    {
-      /* No longer preserve loops, remove them now.  */
-      cfun->curr_properties &= ~PROP_loops;
-      if (current_loops)
-	loop_optimizer_finalize ();
-      return false;
-    } 
-}
+/* The RTL loop superpass.  The actual passes are subpasses.  See passes.c for
+   more on that.  */
 
 namespace {
 
@@ -337,10 +314,33 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_handle_loop2 (); }
+  virtual bool gate (function *);
 
 }; // class pass_loop2
 
+bool
+pass_loop2::gate (function *fun)
+{
+  if (optimize > 0
+      && (flag_move_loop_invariants
+	  || flag_unswitch_loops
+	  || flag_peel_loops
+	  || flag_unroll_loops
+#ifdef HAVE_doloop_end
+	  || (flag_branch_on_count_reg && HAVE_doloop_end)
+#endif
+      ))
+    return true;
+  else
+    {
+      /* No longer preserve loops, remove them now.  */
+      fun->curr_properties &= ~PROP_loops;
+      if (current_loops)
+	loop_optimizer_finalize ();
+      return false;
+    } 
+}
+
 } // anon namespace
 
 rtl_opt_pass *
@@ -461,12 +461,6 @@ make_pass_rtl_loop_done (gcc::context *ctxt)
 
 
 /* Loop invariant code motion.  */
-static bool
-gate_rtl_move_loop_invariants (void)
-{
-  return flag_move_loop_invariants;
-}
-
 static unsigned int
 rtl_move_loop_invariants (void)
 {
@@ -500,7 +494,7 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_rtl_move_loop_invariants (); }
+  virtual bool gate (function *) { return flag_move_loop_invariants; }
   unsigned int execute () { return rtl_move_loop_invariants (); }
 
 }; // class pass_rtl_move_loop_invariants
@@ -514,13 +508,6 @@ make_pass_rtl_move_loop_invariants (gcc::context *ctxt)
 }
 
 
-/* Loop unswitching for RTL.  */
-static bool
-gate_rtl_unswitch (void)
-{
-  return flag_unswitch_loops;
-}
-
 static unsigned int
 rtl_unswitch (void)
 {
@@ -553,7 +540,7 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_rtl_unswitch (); }
+  virtual bool gate (function *) { return flag_unswitch_loops; }
   unsigned int execute () { return rtl_unswitch (); }
 
 }; // class pass_rtl_unswitch
@@ -567,13 +554,6 @@ make_pass_rtl_unswitch (gcc::context *ctxt)
 }
 
 
-/* Loop unswitching for RTL.  */
-static bool
-gate_rtl_unroll_and_peel_loops (void)
-{
-  return (flag_peel_loops || flag_unroll_loops || flag_unroll_all_loops);
-}
-
 static unsigned int
 rtl_unroll_and_peel_loops (void)
 {
@@ -619,7 +599,11 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_rtl_unroll_and_peel_loops (); }
+  virtual bool gate (function *)
+    {
+      return (flag_peel_loops || flag_unroll_loops || flag_unroll_all_loops);
+    }
+
   unsigned int execute () { return rtl_unroll_and_peel_loops (); }
 
 }; // class pass_rtl_unroll_and_peel_loops
@@ -633,17 +617,6 @@ make_pass_rtl_unroll_and_peel_loops (gcc::context *ctxt)
 }
 
 
-/* The doloop optimization.  */
-static bool
-gate_rtl_doloop (void)
-{
-#ifdef HAVE_doloop_end
-  return (flag_branch_on_count_reg && HAVE_doloop_end);
-#else
-  return 0;
-#endif
-}
-
 static unsigned int
 rtl_doloop (void)
 {
@@ -678,11 +651,21 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_rtl_doloop (); }
+  virtual bool gate (function *);
   unsigned int execute () { return rtl_doloop (); }
 
 }; // class pass_rtl_doloop
 
+bool
+pass_rtl_doloop::gate (function *)
+{
+#ifdef HAVE_doloop_end
+  return (flag_branch_on_count_reg && HAVE_doloop_end);
+#else
+  return false;
+#endif
+}
+
 } // anon namespace
 
 rtl_opt_pass *
diff --git a/gcc/lower-subreg.c b/gcc/lower-subreg.c
index 53ef1d9..89d9763 100644
--- a/gcc/lower-subreg.c
+++ b/gcc/lower-subreg.c
@@ -1687,14 +1687,6 @@ decompose_multiword_subregs (bool decompose_copies)
   BITMAP_FREE (subreg_context);
 }
 
-/* Gate function for lower subreg pass.  */
-
-static bool
-gate_handle_lower_subreg (void)
-{
-  return flag_split_wide_types != 0;
-}
-
 /* Implement first lower subreg pass.  */
 
 static unsigned int
@@ -1737,7 +1729,7 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_handle_lower_subreg (); }
+  virtual bool gate (function *) { return flag_split_wide_types != 0; }
   unsigned int execute () { return rest_of_handle_lower_subreg (); }
 
 }; // class pass_lower_subreg
@@ -1775,7 +1767,7 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_handle_lower_subreg (); }
+  virtual bool gate (function *) { return flag_split_wide_types != 0; }
   unsigned int execute () { return rest_of_handle_lower_subreg2 (); }
 
 }; // class pass_lower_subreg2
diff --git a/gcc/mode-switching.c b/gcc/mode-switching.c
index d73135a..e73d6ee 100644
--- a/gcc/mode-switching.c
+++ b/gcc/mode-switching.c
@@ -789,16 +789,6 @@ optimize_mode_switching (void)
 
 #endif /* OPTIMIZE_MODE_SWITCHING */
 
-static bool
-gate_mode_switching (void)
-{
-#ifdef OPTIMIZE_MODE_SWITCHING
-  return true;
-#else
-  return false;
-#endif
-}
-
 static unsigned int
 rest_of_handle_mode_switching (void)
 {
@@ -836,7 +826,15 @@ public:
   /* The epiphany backend creates a second instance of this pass, so we need
      a clone method.  */
   opt_pass * clone () { return new pass_mode_switching (m_ctxt); }
-  bool gate () { return gate_mode_switching (); }
+  virtual bool gate (function *)
+    {
+#ifdef OPTIMIZE_MODE_SWITCHING
+      return true;
+#else
+      return false;
+#endif
+    }
+
   unsigned int execute () { return rest_of_handle_mode_switching (); }
 
 }; // class pass_mode_switching
diff --git a/gcc/modulo-sched.c b/gcc/modulo-sched.c
index a097df3..20e2e62 100644
--- a/gcc/modulo-sched.c
+++ b/gcc/modulo-sched.c
@@ -3323,13 +3323,6 @@ rotate_partial_schedule (partial_schedule_ptr ps, int start_cycle)
 
 #endif /* INSN_SCHEDULING */
 
-static bool
-gate_handle_sms (void)
-{
-  return (optimize > 0 && flag_modulo_sched);
-}
-
-
 /* Run instruction scheduler.  */
 /* Perform SMS module scheduling.  */
 static unsigned int
@@ -3380,7 +3373,11 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_handle_sms (); }
+  virtual bool gate (function *)
+{
+  return (optimize > 0 && flag_modulo_sched);
+}
+
   unsigned int execute () { return rest_of_handle_sms (); }
 
 }; // class pass_sms
diff --git a/gcc/omp-low.c b/gcc/omp-low.c
index cadec81..0e96b88 100644
--- a/gcc/omp-low.c
+++ b/gcc/omp-low.c
@@ -8326,13 +8326,6 @@ execute_expand_omp (void)
 
 /* OMP expansion -- the default pass, run before creation of SSA form.  */
 
-static bool
-gate_expand_omp (void)
-{
-  return ((flag_openmp != 0 || flag_openmp_simd != 0
-	   || flag_cilkplus != 0) && !seen_error ());
-}
-
 namespace {
 
 const pass_data pass_data_expand_omp =
@@ -8357,7 +8350,12 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_expand_omp (); }
+  virtual bool gate (function *)
+    {
+      return ((flag_openmp != 0 || flag_openmp_simd != 0
+	       || flag_cilkplus != 0) && !seen_error ());
+    }
+
   unsigned int execute () { return execute_expand_omp (); }
 
 }; // class pass_expand_omp
@@ -10617,12 +10615,6 @@ diagnose_omp_structured_block_errors (void)
   return 0;
 }
 
-static bool
-gate_diagnose_omp_blocks (void)
-{
-  return flag_openmp || flag_cilkplus;
-}
-
 namespace {
 
 const pass_data pass_data_diagnose_omp_blocks =
@@ -10647,7 +10639,7 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_diagnose_omp_blocks (); }
+  virtual bool gate (function *) { return flag_openmp || flag_cilkplus; }
   unsigned int execute () {
     return diagnose_omp_structured_block_errors ();
   }
@@ -11811,13 +11803,19 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return ((flag_openmp || flag_openmp_simd
-			  || flag_cilkplus || (in_lto_p && !flag_wpa))
-			 && (targetm.simd_clone.compute_vecsize_and_simdlen
-			     != NULL)); }
+  virtual bool gate (function *);
   unsigned int execute () { return ipa_omp_simd_clone (); }
 };
 
+bool
+pass_omp_simd_clone::gate (function *)
+{
+  return ((flag_openmp || flag_openmp_simd
+	   || flag_cilkplus
+	   || (in_lto_p && !flag_wpa))
+	  && (targetm.simd_clone.compute_vecsize_and_simdlen != NULL));
+}
+
 } // anon namespace
 
 simple_ipa_opt_pass *
diff --git a/gcc/passes.c b/gcc/passes.c
index 5d5a94c..b71c11e 100644
--- a/gcc/passes.c
+++ b/gcc/passes.c
@@ -108,7 +108,7 @@ opt_pass::clone ()
 }
 
 bool
-opt_pass::gate ()
+opt_pass::gate (function *)
 {
   return true;
 }
@@ -337,15 +337,6 @@ execute_all_early_local_passes (void)
   return 0;
 }
 
-/* Gate: execute, or not, all of the non-trivial optimizations.  */
-
-static bool
-gate_all_early_local_passes (void)
-{
-	  /* Don't bother doing anything if the program has errors.  */
-  return (!seen_error () && !in_lto_p);
-}
-
 namespace {
 
 const pass_data pass_data_early_local_passes =
@@ -370,7 +361,12 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_all_early_local_passes (); }
+  virtual bool gate (function *)
+    {
+      /* Don't bother doing anything if the program has errors.  */
+      return (!seen_error () && !in_lto_p);
+    }
+
   unsigned int execute () { return execute_all_early_local_passes (); }
 
 }; // class pass_early_local_passes
@@ -383,16 +379,6 @@ make_pass_early_local_passes (gcc::context *ctxt)
   return new pass_early_local_passes (ctxt);
 }
 
-/* Gate: execute, or not, all of the non-trivial optimizations.  */
-
-static bool
-gate_all_early_optimizations (void)
-{
-  return (optimize >= 1
-	  /* Don't bother doing anything if the program has errors.  */
-	  && !seen_error ());
-}
-
 namespace {
 
 const pass_data pass_data_all_early_optimizations =
@@ -417,7 +403,12 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_all_early_optimizations (); }
+  virtual bool gate (function *)
+    {
+      return (optimize >= 1
+	      /* Don't bother doing anything if the program has errors.  */
+	      && !seen_error ());
+    }
 
 }; // class pass_all_early_optimizations
 
@@ -429,14 +420,6 @@ make_pass_all_early_optimizations (gcc::context *ctxt)
   return new pass_all_early_optimizations (ctxt);
 }
 
-/* Gate: execute, or not, all of the non-trivial optimizations.  */
-
-static bool
-gate_all_optimizations (void)
-{
-  return optimize >= 1 && !optimize_debug;
-}
-
 namespace {
 
 const pass_data pass_data_all_optimizations =
@@ -461,7 +444,7 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_all_optimizations (); }
+  virtual bool gate (function *) { return optimize >= 1 && !optimize_debug; }
 
 }; // class pass_all_optimizations
 
@@ -473,14 +456,6 @@ make_pass_all_optimizations (gcc::context *ctxt)
   return new pass_all_optimizations (ctxt);
 }
 
-/* Gate: execute, or not, all of the non-trivial optimizations.  */
-
-static bool
-gate_all_optimizations_g (void)
-{
-  return optimize >= 1 && optimize_debug;
-}
-
 namespace {
 
 const pass_data pass_data_all_optimizations_g =
@@ -505,7 +480,7 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_all_optimizations_g (); }
+  virtual bool gate (function *) { return optimize >= 1 && optimize_debug; }
 
 }; // class pass_all_optimizations_g
 
@@ -517,14 +492,6 @@ make_pass_all_optimizations_g (gcc::context *ctxt)
   return new pass_all_optimizations_g (ctxt);
 }
 
-static bool
-gate_rest_of_compilation (void)
-{
-  /* Early return if there were errors.  We can run afoul of our
-     consistency checks, and there's not really much point in fixing them.  */
-  return !(rtl_dump_and_exit || flag_syntax_only || seen_error ());
-}
-
 namespace {
 
 const pass_data pass_data_rest_of_compilation =
@@ -549,7 +516,12 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_rest_of_compilation (); }
+  virtual bool gate (function *)
+    {
+      /* Early return if there were errors.  We can run afoul of our
+	 consistency checks, and there's not really much point in fixing them.  */
+      return !(rtl_dump_and_exit || flag_syntax_only || seen_error ());
+    }
 
 }; // class pass_rest_of_compilation
 
@@ -561,12 +533,6 @@ make_pass_rest_of_compilation (gcc::context *ctxt)
   return new pass_rest_of_compilation (ctxt);
 }
 
-static bool
-gate_postreload (void)
-{
-  return reload_completed;
-}
-
 namespace {
 
 const pass_data pass_data_postreload =
@@ -591,7 +557,7 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_postreload (); }
+  virtual bool gate (function *) { return reload_completed; }
 
 }; // class pass_postreload
 
@@ -823,7 +789,7 @@ dump_one_pass (opt_pass *pass, int pass_indent)
   const char *pn;
   bool is_on, is_really_on;
 
-  is_on = pass->gate ();
+  is_on = pass->gate (cfun);
   is_really_on = override_gate_status (pass, current_function_decl, is_on);
 
   if (pass->static_pass_number <= 0)
@@ -1976,7 +1942,7 @@ execute_ipa_summary_passes (ipa_opt_pass_d *ipa_pass)
 
       /* Execute all of the IPA_PASSes in the list.  */
       if (ipa_pass->type == IPA_PASS
-	  && pass->gate ()
+	  && pass->gate (cfun)
 	  && ipa_pass->generate_summary)
 	{
 	  pass_init_dump_file (pass);
@@ -2128,7 +2094,7 @@ execute_one_pass (opt_pass *pass)
 
   /* Check whether gate check should be avoided.
      User controls the value of the gate through the parameter "gate_status". */
-  gate_status = pass->gate ();
+  gate_status = pass->gate (cfun);
   gate_status = override_gate_status (pass, current_function_decl, gate_status);
 
   /* Override gate with plugin.  */
@@ -2274,7 +2240,7 @@ ipa_write_summaries_2 (opt_pass *pass, struct lto_out_decl_state *state)
       gcc_assert (pass->type == SIMPLE_IPA_PASS || pass->type == IPA_PASS);
       if (pass->type == IPA_PASS
 	  && ipa_pass->write_summary
-	  && pass->gate ())
+	  && pass->gate (cfun))
 	{
 	  /* If a timevar is present, start it.  */
 	  if (pass->tv_id)
@@ -2392,7 +2358,7 @@ ipa_write_optimization_summaries_1 (opt_pass *pass,
       gcc_assert (pass->type == SIMPLE_IPA_PASS || pass->type == IPA_PASS);
       if (pass->type == IPA_PASS
 	  && ipa_pass->write_optimization_summary
-	  && pass->gate ())
+	  && pass->gate (cfun))
 	{
 	  /* If a timevar is present, start it.  */
 	  if (pass->tv_id)
@@ -2470,7 +2436,7 @@ ipa_read_summaries_1 (opt_pass *pass)
       gcc_assert (!cfun);
       gcc_assert (pass->type == SIMPLE_IPA_PASS || pass->type == IPA_PASS);
 
-      if (pass->gate ())
+      if (pass->gate (cfun))
 	{
 	  if (pass->type == IPA_PASS && ipa_pass->read_summary)
 	    {
@@ -2520,7 +2486,7 @@ ipa_read_optimization_summaries_1 (opt_pass *pass)
       gcc_assert (!cfun);
       gcc_assert (pass->type == SIMPLE_IPA_PASS || pass->type == IPA_PASS);
 
-      if (pass->gate ())
+      if (pass->gate (cfun))
 	{
 	  if (pass->type == IPA_PASS && ipa_pass->read_optimization_summary)
 	    {
@@ -2597,7 +2563,7 @@ execute_ipa_stmt_fixups (opt_pass *pass,
     {
       /* Execute all of the IPA_PASSes in the list.  */
       if (pass->type == IPA_PASS
-	  && pass->gate ())
+	  && pass->gate (cfun))
 	{
 	  ipa_opt_pass_d *ipa_pass = (ipa_opt_pass_d *) pass;
 
diff --git a/gcc/postreload-gcse.c b/gcc/postreload-gcse.c
index 264bd9a..8a804fb 100644
--- a/gcc/postreload-gcse.c
+++ b/gcc/postreload-gcse.c
@@ -1308,13 +1308,6 @@ gcse_after_reload_main (rtx f ATTRIBUTE_UNUSED)
 }
 
 
-static bool
-gate_handle_gcse2 (void)
-{
-  return (optimize > 0 && flag_gcse_after_reload
-	  && optimize_function_for_speed_p (cfun));
-}
-
 
 static unsigned int
 rest_of_handle_gcse2 (void)
@@ -1348,7 +1341,12 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_handle_gcse2 (); }
+  virtual bool gate (function *fun)
+    {
+      return (optimize > 0 && flag_gcse_after_reload
+	      && optimize_function_for_speed_p (fun));
+    }
+
   unsigned int execute () { return rest_of_handle_gcse2 (); }
 
 }; // class pass_gcse2
diff --git a/gcc/postreload.c b/gcc/postreload.c
index 0870183..0568c53 100644
--- a/gcc/postreload.c
+++ b/gcc/postreload.c
@@ -2315,13 +2315,6 @@ move2add_note_store (rtx dst, const_rtx set, void *data)
     }
 }
 
-static bool
-gate_handle_postreload (void)
-{
-  return (optimize > 0 && reload_completed);
-}
-
-
 static unsigned int
 rest_of_handle_postreload (void)
 {
@@ -2363,7 +2356,8 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_handle_postreload (); }
+  virtual bool gate (function *) { return (optimize > 0 && reload_completed); }
+
   unsigned int execute () { return rest_of_handle_postreload (); }
 
 }; // class pass_postreload_cse
diff --git a/gcc/predict.c b/gcc/predict.c
index dccde72..068c187 100644
--- a/gcc/predict.c
+++ b/gcc/predict.c
@@ -3131,12 +3131,6 @@ compute_function_frequency (void)
     }
 }
 
-static bool
-gate_estimate_probability (void)
-{
-  return flag_guess_branch_prob;
-}
-
 /* Build PREDICT_EXPR.  */
 tree
 build_predict_expr (enum br_predictor predictor, enum prediction taken)
@@ -3177,7 +3171,7 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_estimate_probability (); }
+  virtual bool gate (function *) { return flag_guess_branch_prob; }
   unsigned int execute () { return tree_estimate_probability_driver (); }
 
 }; // class pass_profile
diff --git a/gcc/recog.c b/gcc/recog.c
index b7113aa..8afea7e 100644
--- a/gcc/recog.c
+++ b/gcc/recog.c
@@ -3810,12 +3810,6 @@ if_test_bypass_p (rtx out_insn, rtx in_insn)
   return true;
 }
 
-static bool
-gate_handle_peephole2 (void)
-{
-  return (optimize > 0 && flag_peephole2);
-}
-
 static unsigned int
 rest_of_handle_peephole2 (void)
 {
@@ -3852,7 +3846,7 @@ public:
   /* The epiphany backend creates a second instance of this pass, so we need
      a clone method.  */
   opt_pass * clone () { return new pass_peephole2 (m_ctxt); }
-  bool gate () { return gate_handle_peephole2 (); }
+  virtual bool gate (function *) { return (optimize > 0 && flag_peephole2); }
   unsigned int execute () { return rest_of_handle_peephole2 (); }
 
 }; // class pass_peephole2
@@ -3958,24 +3952,6 @@ make_pass_split_after_reload (gcc::context *ctxt)
   return new pass_split_after_reload (ctxt);
 }
 
-static bool
-gate_handle_split_before_regstack (void)
-{
-#if HAVE_ATTR_length && defined (STACK_REGS)
-  /* If flow2 creates new instructions which need splitting
-     and scheduling after reload is not done, they might not be
-     split until final which doesn't allow splitting
-     if HAVE_ATTR_length.  */
-# ifdef INSN_SCHEDULING
-  return (optimize && !flag_schedule_insns_after_reload);
-# else
-  return (optimize);
-# endif
-#else
-  return 0;
-#endif
-}
-
 static unsigned int
 rest_of_handle_split_before_regstack (void)
 {
@@ -4007,13 +3983,31 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_handle_split_before_regstack (); }
+  virtual bool gate (function *);
   unsigned int execute () {
     return rest_of_handle_split_before_regstack ();
   }
 
 }; // class pass_split_before_regstack
 
+bool
+pass_split_before_regstack::gate (function *)
+{
+#if HAVE_ATTR_length && defined (STACK_REGS)
+  /* If flow2 creates new instructions which need splitting
+     and scheduling after reload is not done, they might not be
+     split until final which doesn't allow splitting
+     if HAVE_ATTR_length.  */
+# ifdef INSN_SCHEDULING
+  return (optimize && !flag_schedule_insns_after_reload);
+# else
+  return (optimize);
+# endif
+#else
+  return 0;
+#endif
+}
+
 } // anon namespace
 
 rtl_opt_pass *
@@ -4022,16 +4016,6 @@ make_pass_split_before_regstack (gcc::context *ctxt)
   return new pass_split_before_regstack (ctxt);
 }
 
-static bool
-gate_handle_split_before_sched2 (void)
-{
-#ifdef INSN_SCHEDULING
-  return optimize > 0 && flag_schedule_insns_after_reload;
-#else
-  return 0;
-#endif
-}
-
 static unsigned int
 rest_of_handle_split_before_sched2 (void)
 {
@@ -4065,7 +4049,15 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_handle_split_before_sched2 (); }
+  virtual bool gate (function *)
+    {
+#ifdef INSN_SCHEDULING
+      return optimize > 0 && flag_schedule_insns_after_reload;
+#else
+      return false;
+#endif
+    }
+
   unsigned int execute () { return rest_of_handle_split_before_sched2 (); }
 
 }; // class pass_split_before_sched2
@@ -4078,18 +4070,6 @@ make_pass_split_before_sched2 (gcc::context *ctxt)
   return new pass_split_before_sched2 (ctxt);
 }
 
-/* The placement of the splitting that we do for shorten_branches
-   depends on whether regstack is used by the target or not.  */
-static bool
-gate_do_final_split (void)
-{
-#if HAVE_ATTR_length && !defined (STACK_REGS)
-  return 1;
-#else
-  return 0;
-#endif
-}
-
 namespace {
 
 const pass_data pass_data_split_for_shorten_branches =
@@ -4114,7 +4094,17 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_do_final_split (); }
+  virtual bool gate (function *)
+    {
+      /* The placement of the splitting that we do for shorten_branches
+	 depends on whether regstack is used by the target or not.  */
+#if HAVE_ATTR_length && !defined (STACK_REGS)
+      return true;
+#else
+      return false;
+#endif
+    }
+
   unsigned int execute () { return split_all_insns_noflow (); }
 
 }; // class pass_split_for_shorten_branches
diff --git a/gcc/ree.c b/gcc/ree.c
index 09dfa61..435bb88 100644
--- a/gcc/ree.c
+++ b/gcc/ree.c
@@ -1093,14 +1093,6 @@ rest_of_handle_ree (void)
   return 0;
 }
 
-/* Run REE pass when flag_ree is set at optimization level > 0.  */
-
-static bool
-gate_handle_ree (void)
-{
-  return (optimize > 0 && flag_ree);
-}
-
 namespace {
 
 const pass_data pass_data_ree =
@@ -1125,7 +1117,7 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_handle_ree (); }
+  virtual bool gate (function *) { return (optimize > 0 && flag_ree); }
   unsigned int execute () { return rest_of_handle_ree (); }
 
 }; // class pass_ree
diff --git a/gcc/reg-stack.c b/gcc/reg-stack.c
index 02e3e09..f8f8658 100644
--- a/gcc/reg-stack.c
+++ b/gcc/reg-stack.c
@@ -3285,16 +3285,6 @@ reg_to_stack (void)
 }
 #endif /* STACK_REGS */
 
-static bool
-gate_handle_stack_regs (void)
-{
-#ifdef STACK_REGS
-  return 1;
-#else
-  return 0;
-#endif
-}
-
 namespace {
 
 const pass_data pass_data_stack_regs =
@@ -3319,7 +3309,14 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_handle_stack_regs (); }
+  virtual bool gate (function *)
+    {
+#ifdef STACK_REGS
+      return true;
+#else
+      return false;
+#endif
+    }
 
 }; // class pass_stack_regs
 
diff --git a/gcc/regcprop.c b/gcc/regcprop.c
index a7dbbc3..24992e4 100644
--- a/gcc/regcprop.c
+++ b/gcc/regcprop.c
@@ -1247,13 +1247,6 @@ validate_value_data (struct value_data *vd)
 }
 #endif
 
-static bool
-gate_handle_cprop (void)
-{
-  return (optimize > 0 && (flag_cprop_registers));
-}
-
-
 namespace {
 
 const pass_data pass_data_cprop_hardreg =
@@ -1278,7 +1271,11 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_handle_cprop (); }
+  virtual bool gate (function *)
+    {
+      return (optimize > 0 && (flag_cprop_registers));
+    }
+
   unsigned int execute () { return copyprop_hardreg_forward (); }
 
 }; // class pass_cprop_hardreg
diff --git a/gcc/regrename.c b/gcc/regrename.c
index 30f7abc..321d5bf 100644
--- a/gcc/regrename.c
+++ b/gcc/regrename.c
@@ -1836,12 +1836,6 @@ regrename_optimize (void)
   return 0;
 }
 
-static bool
-gate_handle_regrename (void)
-{
-  return (optimize > 0 && (flag_rename_registers));
-}
-
 namespace {
 
 const pass_data pass_data_regrename =
@@ -1866,7 +1860,11 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_handle_regrename (); }
+  virtual bool gate (function *)
+    {
+      return (optimize > 0 && (flag_rename_registers));
+    }
+
   unsigned int execute () { return regrename_optimize (); }
 
 }; // class pass_regrename
diff --git a/gcc/reorg.c b/gcc/reorg.c
index fff342f..22f0b5a 100644
--- a/gcc/reorg.c
+++ b/gcc/reorg.c
@@ -3863,17 +3863,6 @@ dbr_schedule (rtx first)
 }
 #endif /* DELAY_SLOTS */
 
-static bool
-gate_handle_delay_slots (void)
-{
-#ifdef DELAY_SLOTS
-  /* At -O0 dataflow info isn't updated after RA.  */
-  return optimize > 0 && flag_delayed_branch && !crtl->dbr_scheduled_p;
-#else
-  return 0;
-#endif
-}
-
 /* Run delay slot optimization.  */
 static unsigned int
 rest_of_handle_delay_slots (void)
@@ -3908,11 +3897,22 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_handle_delay_slots (); }
+  virtual bool gate (function *);
   unsigned int execute () { return rest_of_handle_delay_slots (); }
 
 }; // class pass_delay_slots
 
+bool
+pass_delay_slots::gate (function *)
+{
+#ifdef DELAY_SLOTS
+  /* At -O0 dataflow info isn't updated after RA.  */
+  return optimize > 0 && flag_delayed_branch && !crtl->dbr_scheduled_p;
+#else
+  return 0;
+#endif
+}
+
 } // anon namespace
 
 rtl_opt_pass *
@@ -3922,12 +3922,6 @@ make_pass_delay_slots (gcc::context *ctxt)
 }
 
 /* Machine dependent reorg pass.  */
-static bool
-gate_handle_machine_reorg (void)
-{
-  return targetm.machine_dependent_reorg != 0;
-}
-
 
 static unsigned int
 rest_of_handle_machine_reorg (void)
@@ -3960,7 +3954,11 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_handle_machine_reorg (); }
+  virtual bool gate (function *)
+    {
+      return targetm.machine_dependent_reorg != 0;
+    }
+
   unsigned int execute () { return rest_of_handle_machine_reorg (); }
 
 }; // class pass_machine_reorg
diff --git a/gcc/sched-rgn.c b/gcc/sched-rgn.c
index 18b50a4..e0a80c2 100644
--- a/gcc/sched-rgn.c
+++ b/gcc/sched-rgn.c
@@ -3591,16 +3591,6 @@ advance_target_bb (basic_block bb, rtx insn)
 
 #endif
 
-static bool
-gate_handle_live_range_shrinkage (void)
-{
-#ifdef INSN_SCHEDULING
-  return flag_live_range_shrinkage;
-#else
-  return 0;
-#endif
-}
-
 /* Run instruction scheduler.  */
 static unsigned int
 rest_of_handle_live_range_shrinkage (void)
@@ -3618,16 +3608,6 @@ rest_of_handle_live_range_shrinkage (void)
   return 0;
 }
 
-static bool
-gate_handle_sched (void)
-{
-#ifdef INSN_SCHEDULING
-  return optimize > 0 && flag_schedule_insns && dbg_cnt (sched_func);
-#else
-  return 0;
-#endif
-}
-
 /* Run instruction scheduler.  */
 static unsigned int
 rest_of_handle_sched (void)
@@ -3642,17 +3622,6 @@ rest_of_handle_sched (void)
   return 0;
 }
 
-static bool
-gate_handle_sched2 (void)
-{
-#ifdef INSN_SCHEDULING
-  return optimize > 0 && flag_schedule_insns_after_reload
-    && !targetm.delay_sched2 && dbg_cnt (sched2_func);
-#else
-  return 0;
-#endif
-}
-
 /* Run second scheduling pass after reload.  */
 static unsigned int
 rest_of_handle_sched2 (void)
@@ -3699,7 +3668,15 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_handle_live_range_shrinkage (); }
+  virtual bool gate (function *)
+    {
+#ifdef INSN_SCHEDULING
+      return flag_live_range_shrinkage;
+#else
+      return 0;
+#endif
+    }
+
   unsigned int execute () { return rest_of_handle_live_range_shrinkage (); }
 
 }; // class pass_live_range_shrinkage
@@ -3737,11 +3714,21 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_handle_sched (); }
+  virtual bool gate (function *);
   unsigned int execute () { return rest_of_handle_sched (); }
 
 }; // class pass_sched
 
+bool
+pass_sched::gate (function *)
+{
+#ifdef INSN_SCHEDULING
+  return optimize > 0 && flag_schedule_insns && dbg_cnt (sched_func);
+#else
+  return 0;
+#endif
+}
+
 } // anon namespace
 
 rtl_opt_pass *
@@ -3775,11 +3762,22 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_handle_sched2 (); }
+  virtual bool gate (function *);
   unsigned int execute () { return rest_of_handle_sched2 (); }
 
 }; // class pass_sched2
 
+bool
+pass_sched2::gate (function *)
+{
+#ifdef INSN_SCHEDULING
+  return optimize > 0 && flag_schedule_insns_after_reload
+    && !targetm.delay_sched2 && dbg_cnt (sched2_func);
+#else
+  return 0;
+#endif
+}
+
 } // anon namespace
 
 rtl_opt_pass *
diff --git a/gcc/store-motion.c b/gcc/store-motion.c
index 5aacaad..7c57754 100644
--- a/gcc/store-motion.c
+++ b/gcc/store-motion.c
@@ -1223,15 +1223,6 @@ one_store_motion_pass (void)
 }
 
 
-static bool
-gate_rtl_store_motion (void)
-{
-  return optimize > 0 && flag_gcse_sm
-    && !cfun->calls_setjmp
-    && optimize_function_for_speed_p (cfun)
-    && dbg_cnt (store_motion);
-}
-
 static unsigned int
 execute_rtl_store_motion (void)
 {
@@ -1266,11 +1257,20 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_rtl_store_motion (); }
+  virtual bool gate (function *);
   unsigned int execute () { return execute_rtl_store_motion (); }
 
 }; // class pass_rtl_store_motion
 
+bool
+pass_rtl_store_motion::gate (function *fun)
+{
+  return optimize > 0 && flag_gcse_sm
+    && !fun->calls_setjmp
+    && optimize_function_for_speed_p (fun)
+    && dbg_cnt (store_motion);
+}
+
 } // anon namespace
 
 rtl_opt_pass *
diff --git a/gcc/testsuite/g++.dg/plugin/dumb_plugin.c b/gcc/testsuite/g++.dg/plugin/dumb_plugin.c
index d73bea8..a3b04a2 100644
--- a/gcc/testsuite/g++.dg/plugin/dumb_plugin.c
+++ b/gcc/testsuite/g++.dg/plugin/dumb_plugin.c
@@ -52,12 +52,6 @@ execute_dumb_plugin_example (void)
   return 0;
 }
 
-static bool
-gate_dumb_plugin_example (void)
-{
-  return true;
-}
-
 namespace {
 
 const pass_data pass_data_dumb_plugin_example =
@@ -82,7 +76,6 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_dumb_plugin_example (); }
   unsigned int execute () { return execute_dumb_plugin_example (); }
 
 }; // class pass_dumb_plugin_example
diff --git a/gcc/testsuite/g++.dg/plugin/selfassign.c b/gcc/testsuite/g++.dg/plugin/selfassign.c
index 8df8579..033047b 100644
--- a/gcc/testsuite/g++.dg/plugin/selfassign.c
+++ b/gcc/testsuite/g++.dg/plugin/selfassign.c
@@ -270,14 +270,6 @@ execute_warn_self_assign (void)
   return 0;
 }
 
-/* Pass gate function. Currently always returns true.  */
-
-static bool
-gate_warn_self_assign (void)
-{
-  return true;
-}
-
 namespace {
 
 const pass_data pass_data_warn_self_assign =
@@ -302,7 +294,7 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_warn_self_assign (); }
+  bool gate (function *) { return true; }
   unsigned int execute () { return execute_warn_self_assign (); }
 
 }; // class pass_warn_self_assign
diff --git a/gcc/testsuite/gcc.dg/plugin/one_time_plugin.c b/gcc/testsuite/gcc.dg/plugin/one_time_plugin.c
index 33106ad..18e8b07 100644
--- a/gcc/testsuite/gcc.dg/plugin/one_time_plugin.c
+++ b/gcc/testsuite/gcc.dg/plugin/one_time_plugin.c
@@ -49,7 +49,7 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate ();
+  virtual bool gate (function *);
   unsigned int execute ();
 
 private:
@@ -58,7 +58,7 @@ private:
 
 } // anon namespace
 
-bool one_pass::gate (void)
+bool one_pass::gate (function *)
 {
   return true;
 }
diff --git a/gcc/testsuite/gcc.dg/plugin/selfassign.c b/gcc/testsuite/gcc.dg/plugin/selfassign.c
index 8df8579..098df06 100644
--- a/gcc/testsuite/gcc.dg/plugin/selfassign.c
+++ b/gcc/testsuite/gcc.dg/plugin/selfassign.c
@@ -270,14 +270,6 @@ execute_warn_self_assign (void)
   return 0;
 }
 
-/* Pass gate function. Currently always returns true.  */
-
-static bool
-gate_warn_self_assign (void)
-{
-  return true;
-}
-
 namespace {
 
 const pass_data pass_data_warn_self_assign =
@@ -302,7 +294,6 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_warn_self_assign (); }
   unsigned int execute () { return execute_warn_self_assign (); }
 
 }; // class pass_warn_self_assign
diff --git a/gcc/tracer.c b/gcc/tracer.c
index 73e3209..794d385 100644
--- a/gcc/tracer.c
+++ b/gcc/tracer.c
@@ -398,12 +398,6 @@ tracer (void)
   return changed ? TODO_cleanup_cfg : 0;
 }
 
-static bool
-gate_tracer (void)
-{
-  return (optimize > 0 && flag_tracer && flag_reorder_blocks);
-}
-
 namespace {
 
 const pass_data pass_data_tracer =
@@ -428,7 +422,11 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_tracer (); }
+  virtual bool gate (function *)
+    {
+      return (optimize > 0 && flag_tracer && flag_reorder_blocks);
+    }
+
   unsigned int execute () { return tracer (); }
 
 }; // class pass_tracer
diff --git a/gcc/trans-mem.c b/gcc/trans-mem.c
index a259b77..be876f5 100644
--- a/gcc/trans-mem.c
+++ b/gcc/trans-mem.c
@@ -456,14 +456,6 @@ build_tm_abort_call (location_t loc, bool is_outer)
 					     AR_USERABORT
 					     | (is_outer ? AR_OUTERABORT : 0)));
 }
-
-/* Common gateing function for several of the TM passes.  */
-
-static bool
-gate_tm (void)
-{
-  return flag_tm;
-}
 
 /* Map for aribtrary function replacement under TM, as created
    by the tm_wrap attribute.  */
@@ -863,7 +855,7 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_tm (); }
+  virtual bool gate (function *) { return flag_tm; }
   unsigned int execute () { return diagnose_tm_blocks (); }
 
 }; // class pass_diagnose_tm_blocks
@@ -1785,7 +1777,7 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_tm (); }
+  virtual bool gate (function *) { return flag_tm; }
   unsigned int execute () { return execute_lower_tm (); }
 
 }; // class pass_lower_tm
@@ -2062,7 +2054,7 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_tm_init (); }
+  virtual bool gate (function *) { return gate_tm_init (); }
 
 }; // class pass_tm_init
 
@@ -3929,12 +3921,6 @@ execute_tm_memopt (void)
   return 0;
 }
 
-static bool
-gate_tm_memopt (void)
-{
-  return flag_tm && optimize > 0;
-}
-
 namespace {
 
 const pass_data pass_data_tm_memopt =
@@ -3959,7 +3945,7 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_tm_memopt (); }
+  virtual bool gate (function *) { return flag_tm && optimize > 0; }
   unsigned int execute () { return execute_tm_memopt (); }
 
 }; // class pass_tm_memopt
@@ -5594,7 +5580,7 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_tm (); }
+  virtual bool gate (function *) { return flag_tm; }
   unsigned int execute () { return ipa_tm_execute (); }
 
 }; // class pass_ipa_tm
diff --git a/gcc/tree-call-cdce.c b/gcc/tree-call-cdce.c
index 3293493..c271493 100644
--- a/gcc/tree-call-cdce.c
+++ b/gcc/tree-call-cdce.c
@@ -917,15 +917,6 @@ tree_call_cdce (void)
   return 0;
 }
 
-static bool
-gate_call_cdce (void)
-{
-  /* The limit constants used in the implementation
-     assume IEEE floating point format.  Other formats
-     can be supported in the future if needed.  */
-  return flag_tree_builtin_call_dce != 0 && optimize_function_for_speed_p (cfun);
-}
-
 namespace {
 
 const pass_data pass_data_call_cdce =
@@ -950,7 +941,15 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_call_cdce (); }
+  virtual bool gate (function *fun)
+    {
+      /* The limit constants used in the implementation
+	 assume IEEE floating point format.  Other formats
+	 can be supported in the future if needed.  */
+      return flag_tree_builtin_call_dce != 0
+       	&& optimize_function_for_speed_p (fun);
+    }
+
   unsigned int execute () { return tree_call_cdce (); }
 
 }; // class pass_call_cdce
diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c
index 739ca54..08e0280 100644
--- a/gcc/tree-cfg.c
+++ b/gcc/tree-cfg.c
@@ -8355,12 +8355,6 @@ run_warn_unused_result (void)
   return 0;
 }
 
-static bool
-gate_warn_unused_result (void)
-{
-  return flag_warn_unused_result;
-}
-
 namespace {
 
 const pass_data pass_data_warn_unused_result =
@@ -8385,7 +8379,7 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_warn_unused_result (); }
+  virtual bool gate (function *) { return flag_warn_unused_result; }
   unsigned int execute () { return run_warn_unused_result (); }
 
 }; // class pass_warn_unused_result
diff --git a/gcc/tree-cfgcleanup.c b/gcc/tree-cfgcleanup.c
index 914523d..19433f9 100644
--- a/gcc/tree-cfgcleanup.c
+++ b/gcc/tree-cfgcleanup.c
@@ -1035,12 +1035,6 @@ merge_phi_nodes (void)
   return 0;
 }
 
-static bool
-gate_merge_phi (void)
-{
-  return 1;
-}
-
 namespace {
 
 const pass_data pass_data_merge_phi =
@@ -1066,7 +1060,6 @@ public:
 
   /* opt_pass methods: */
   opt_pass * clone () { return new pass_merge_phi (m_ctxt); }
-  bool gate () { return gate_merge_phi (); }
   unsigned int execute () { return merge_phi_nodes (); }
 
 }; // class pass_merge_phi
diff --git a/gcc/tree-complex.c b/gcc/tree-complex.c
index 283c827..9ec83d9 100644
--- a/gcc/tree-complex.c
+++ b/gcc/tree-complex.c
@@ -1693,14 +1693,6 @@ make_pass_lower_complex (gcc::context *ctxt)
 }
 
 
-static bool
-gate_no_optimization (void)
-{
-  /* With errors, normal optimization passes are not run.  If we don't
-     lower complex operations at all, rtl expansion will abort.  */
-  return !(cfun->curr_properties & PROP_gimple_lcx);
-}
-
 namespace {
 
 const pass_data pass_data_lower_complex_O0 =
@@ -1725,7 +1717,13 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_no_optimization (); }
+  virtual bool gate (function *fun)
+    {
+      /* With errors, normal optimization passes are not run.  If we don't
+	 lower complex operations at all, rtl expansion will abort.  */
+      return !(fun->curr_properties & PROP_gimple_lcx);
+    }
+
   unsigned int execute () { return tree_lower_complex (); }
 
 }; // class pass_lower_complex_O0
diff --git a/gcc/tree-eh.c b/gcc/tree-eh.c
index f51f18c..41f96c4 100644
--- a/gcc/tree-eh.c
+++ b/gcc/tree-eh.c
@@ -3115,12 +3115,6 @@ refactor_eh (void)
   return 0;
 }
 
-static bool
-gate_refactor_eh (void)
-{
-  return flag_exceptions != 0;
-}
-
 namespace {
 
 const pass_data pass_data_refactor_eh =
@@ -3145,7 +3139,7 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_refactor_eh (); }
+  virtual bool gate (function *) { return flag_exceptions != 0; }
   unsigned int execute () { return refactor_eh (); }
 
 }; // class pass_refactor_eh
@@ -3341,12 +3335,6 @@ execute_lower_resx (void)
   return any_rewritten ? TODO_update_ssa_only_virtuals : 0;
 }
 
-static bool
-gate_lower_resx (void)
-{
-  return flag_exceptions != 0;
-}
-
 namespace {
 
 const pass_data pass_data_lower_resx =
@@ -3371,7 +3359,7 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_lower_resx (); }
+  virtual bool gate (function *) { return flag_exceptions != 0; }
   unsigned int execute () { return execute_lower_resx (); }
 
 }; // class pass_lower_resx
@@ -3749,12 +3737,6 @@ execute_lower_eh_dispatch (void)
   return flags;
 }
 
-static bool
-gate_lower_eh_dispatch (void)
-{
-  return cfun->eh->region_tree != NULL;
-}
-
 namespace {
 
 const pass_data pass_data_lower_eh_dispatch =
@@ -3779,7 +3761,8 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_lower_eh_dispatch (); }
+  virtual bool gate (function *fun) { return fun->eh->region_tree != NULL; }
+
   unsigned int execute () { return execute_lower_eh_dispatch (); }
 
 }; // class pass_lower_eh_dispatch
@@ -4596,12 +4579,6 @@ execute_cleanup_eh (void)
   return ret;
 }
 
-static bool
-gate_cleanup_eh (void)
-{
-  return cfun->eh != NULL && cfun->eh->region_tree != NULL;
-}
-
 namespace {
 
 const pass_data pass_data_cleanup_eh =
@@ -4627,7 +4604,11 @@ public:
 
   /* opt_pass methods: */
   opt_pass * clone () { return new pass_cleanup_eh (m_ctxt); }
-  bool gate () { return gate_cleanup_eh (); }
+  virtual bool gate (function *fun)
+    {
+      return fun->eh != NULL && fun->eh->region_tree != NULL;
+    }
+
   unsigned int execute () { return execute_cleanup_eh (); }
 
 }; // class pass_cleanup_eh
diff --git a/gcc/tree-emutls.c b/gcc/tree-emutls.c
index 84aa008..280a606 100644
--- a/gcc/tree-emutls.c
+++ b/gcc/tree-emutls.c
@@ -816,14 +816,6 @@ ipa_lower_emutls (void)
   return TODO_verify_all;
 }
 
-/* If the target supports TLS natively, we need do nothing here.  */
-
-static bool
-gate_emutls (void)
-{
-  return !targetm.have_tls;
-}
-
 namespace {
 
 const pass_data pass_data_ipa_lower_emutls =
@@ -848,7 +840,12 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_emutls (); }
+  virtual bool gate (function *)
+    {
+      /* If the target supports TLS natively, we need do nothing here.  */
+      return !targetm.have_tls;
+    }
+
   unsigned int execute () { return ipa_lower_emutls (); }
 
 }; // class pass_ipa_lower_emutls
diff --git a/gcc/tree-if-conv.c b/gcc/tree-if-conv.c
index b87c476..90b62a8 100644
--- a/gcc/tree-if-conv.c
+++ b/gcc/tree-if-conv.c
@@ -2013,17 +2013,6 @@ main_tree_if_conversion (void)
   return todo;
 }
 
-/* Returns true when the if-conversion pass is enabled.  */
-
-static bool
-gate_tree_if_conversion (void)
-{
-  return (((flag_tree_loop_vectorize || cfun->has_force_vectorize_loops)
-	   && flag_tree_loop_if_convert != 0)
-	  || flag_tree_loop_if_convert == 1
-	  || flag_tree_loop_if_convert_stores == 1);
-}
-
 namespace {
 
 const pass_data pass_data_if_conversion =
@@ -2049,11 +2038,20 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_tree_if_conversion (); }
+  virtual bool gate (function *);
   unsigned int execute () { return main_tree_if_conversion (); }
 
 }; // class pass_if_conversion
 
+bool
+pass_if_conversion::gate (function *fun)
+{
+  return (((flag_tree_loop_vectorize || fun->has_force_vectorize_loops)
+	   && flag_tree_loop_if_convert != 0)
+	  || flag_tree_loop_if_convert == 1
+	  || flag_tree_loop_if_convert_stores == 1);
+}
+
 } // anon namespace
 
 gimple_opt_pass *
diff --git a/gcc/tree-into-ssa.c b/gcc/tree-into-ssa.c
index dec5a5b..332901d 100644
--- a/gcc/tree-into-ssa.c
+++ b/gcc/tree-into-ssa.c
@@ -2365,15 +2365,6 @@ rewrite_into_ssa (void)
   return 0;
 }
 
-/* Gate for IPCP optimization.  */
-
-static bool
-gate_into_ssa (void)
-{
-  /* Do nothing for funcions that was produced already in SSA form.  */
-  return !(cfun->curr_properties & PROP_ssa);
-}
-
 namespace {
 
 const pass_data pass_data_build_ssa =
@@ -2398,7 +2389,12 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_into_ssa (); }
+  virtual bool gate (function *fun)
+    {
+      /* Do nothing for funcions that was produced already in SSA form.  */
+      return !(fun->curr_properties & PROP_ssa);
+    }
+
   unsigned int execute () { return rewrite_into_ssa (); }
 
 }; // class pass_build_ssa
diff --git a/gcc/tree-loop-distribution.c b/gcc/tree-loop-distribution.c
index dcc61c7..0a15412 100644
--- a/gcc/tree-loop-distribution.c
+++ b/gcc/tree-loop-distribution.c
@@ -1790,13 +1790,6 @@ out:
   return 0;
 }
 
-static bool
-gate_tree_loop_distribution (void)
-{
-  return flag_tree_loop_distribution
-    || flag_tree_loop_distribute_patterns;
-}
-
 namespace {
 
 const pass_data pass_data_loop_distribution =
@@ -1821,7 +1814,12 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_tree_loop_distribution (); }
+  virtual bool gate (function *)
+    {
+      return flag_tree_loop_distribution
+	|| flag_tree_loop_distribute_patterns;
+    }
+
   unsigned int execute () { return tree_loop_distribution (); }
 
 }; // class pass_loop_distribution
diff --git a/gcc/tree-nrv.c b/gcc/tree-nrv.c
index a39bc5e..71f8d68 100644
--- a/gcc/tree-nrv.c
+++ b/gcc/tree-nrv.c
@@ -272,12 +272,6 @@ tree_nrv (void)
   return 0;
 }
 
-static bool
-gate_pass_return_slot (void)
-{
-  return optimize > 0;
-}
-
 namespace {
 
 const pass_data pass_data_nrv =
@@ -302,7 +296,8 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_pass_return_slot (); }
+  virtual bool gate (function *) { return optimize > 0; }
+
   unsigned int execute () { return tree_nrv (); }
 
 }; // class pass_nrv
diff --git a/gcc/tree-parloops.c b/gcc/tree-parloops.c
index e346074..a46fa51 100644
--- a/gcc/tree-parloops.c
+++ b/gcc/tree-parloops.c
@@ -2253,12 +2253,6 @@ parallelize_loops (void)
 
 /* Parallelization.  */
 
-static bool
-gate_tree_parallelize_loops (void)
-{
-  return flag_tree_parallelize_loops > 1;
-}
-
 static unsigned
 tree_parallelize_loops (void)
 {
@@ -2294,7 +2288,7 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_tree_parallelize_loops (); }
+  virtual bool gate (function *) { return flag_tree_parallelize_loops > 1; }
   unsigned int execute () { return tree_parallelize_loops (); }
 
 }; // class pass_parallelize_loops
diff --git a/gcc/tree-pass.h b/gcc/tree-pass.h
index 9bb6455..9de2822 100644
--- a/gcc/tree-pass.h
+++ b/gcc/tree-pass.h
@@ -25,6 +25,8 @@ along with GCC; see the file COPYING3.  If not see
 #include "timevar.h"
 #include "dumpfile.h"
 
+struct function;
+
 /* Optimization pass type.  */
 enum opt_pass_type
 {
@@ -88,7 +90,7 @@ public:
 
   /* This pass and all sub-passes are executed only if the function returns
      true.  The default implementation returns true.  */
-  virtual bool gate ();
+  virtual bool gate (function *fun);
 
   /* This is the code to run.  If has_execute is false, then there should
      be sub-passes otherwise this pass does nothing.
diff --git a/gcc/tree-predcom.c b/gcc/tree-predcom.c
index 859a112..7dd86e1 100644
--- a/gcc/tree-predcom.c
+++ b/gcc/tree-predcom.c
@@ -2573,12 +2573,6 @@ run_tree_predictive_commoning (void)
   return tree_predictive_commoning ();
 }
 
-static bool
-gate_tree_predictive_commoning (void)
-{
-  return flag_predictive_commoning != 0;
-}
-
 namespace {
 
 const pass_data pass_data_predcom =
@@ -2603,7 +2597,7 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_tree_predictive_commoning (); }
+  virtual bool gate (function *) { return flag_predictive_commoning != 0; }
   unsigned int execute () { return run_tree_predictive_commoning (); }
 
 }; // class pass_predcom
diff --git a/gcc/tree-profile.c b/gcc/tree-profile.c
index 0372c92..b7d0466 100644
--- a/gcc/tree-profile.c
+++ b/gcc/tree-profile.c
@@ -663,16 +663,6 @@ tree_profiling (void)
   return 0;
 }
 
-/* When profile instrumentation, use or test coverage shall be performed.  */
-
-static bool
-gate_tree_profile_ipa (void)
-{
-  return (!in_lto_p
-	  && (flag_branch_probabilities || flag_test_coverage
-	      || profile_arc_flag));
-}
-
 namespace {
 
 const pass_data pass_data_ipa_tree_profile =
@@ -697,11 +687,20 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_tree_profile_ipa (); }
+  virtual bool gate (function *);
   unsigned int execute () { return tree_profiling (); }
 
 }; // class pass_ipa_tree_profile
 
+bool
+pass_ipa_tree_profile::gate (function *)
+{
+  /* When profile instrumentation, use or test coverage shall be performed.  */
+  return (!in_lto_p
+	  && (flag_branch_probabilities || flag_test_coverage
+	      || profile_arc_flag));
+}
+
 } // anon namespace
 
 simple_ipa_opt_pass *
diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c
index acca2a7..27f71a3 100644
--- a/gcc/tree-sra.c
+++ b/gcc/tree-sra.c
@@ -3524,7 +3524,7 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_intra_sra (); }
+  virtual bool gate (function *) { return gate_intra_sra (); }
   unsigned int execute () { return early_intra_sra (); }
 
 }; // class pass_sra_early
@@ -3561,7 +3561,7 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_intra_sra (); }
+  virtual bool gate (function *) { return gate_intra_sra (); }
   unsigned int execute () { return late_intra_sra (); }
 
 }; // class pass_sra
@@ -5051,13 +5051,6 @@ ipa_early_sra (void)
   return ret;
 }
 
-/* Return if early ipa sra shall be performed.  */
-static bool
-ipa_early_sra_gate (void)
-{
-  return flag_ipa_sra && dbg_cnt (eipa_sra);
-}
-
 namespace {
 
 const pass_data pass_data_early_ipa_sra =
@@ -5082,7 +5075,7 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return ipa_early_sra_gate (); }
+  virtual bool gate (function *) { return flag_ipa_sra && dbg_cnt (eipa_sra); }
   unsigned int execute () { return ipa_early_sra (); }
 
 }; // class pass_early_ipa_sra
diff --git a/gcc/tree-ssa-ccp.c b/gcc/tree-ssa-ccp.c
index c7a7e89..c4a5c71 100644
--- a/gcc/tree-ssa-ccp.c
+++ b/gcc/tree-ssa-ccp.c
@@ -2287,13 +2287,6 @@ do_ssa_ccp (void)
 }
 
 
-static bool
-gate_ccp (void)
-{
-  return flag_tree_ccp != 0;
-}
-
-
 namespace {
 
 const pass_data pass_data_ccp =
@@ -2320,7 +2313,7 @@ public:
 
   /* opt_pass methods: */
   opt_pass * clone () { return new pass_ccp (m_ctxt); }
-  bool gate () { return gate_ccp (); }
+  virtual bool gate (function *) { return flag_tree_ccp != 0; }
   unsigned int execute () { return do_ssa_ccp (); }
 
 }; // class pass_ccp
diff --git a/gcc/tree-ssa-copy.c b/gcc/tree-ssa-copy.c
index fc26d03..bd6ac04 100644
--- a/gcc/tree-ssa-copy.c
+++ b/gcc/tree-ssa-copy.c
@@ -644,12 +644,6 @@ execute_copy_prop (void)
   return 0;
 }
 
-static bool
-gate_copy_prop (void)
-{
-  return flag_tree_copy_prop != 0;
-}
-
 namespace {
 
 const pass_data pass_data_copy_prop =
@@ -676,7 +670,7 @@ public:
 
   /* opt_pass methods: */
   opt_pass * clone () { return new pass_copy_prop (m_ctxt); }
-  bool gate () { return gate_copy_prop (); }
+  virtual bool gate (function *) { return flag_tree_copy_prop != 0; }
   unsigned int execute () { return execute_copy_prop (); }
 
 }; // class pass_copy_prop
diff --git a/gcc/tree-ssa-copyrename.c b/gcc/tree-ssa-copyrename.c
index 0da3d82..65d8044 100644
--- a/gcc/tree-ssa-copyrename.c
+++ b/gcc/tree-ssa-copyrename.c
@@ -435,14 +435,6 @@ rename_ssa_copies (void)
   return 0;
 }
 
-/* Return true if copy rename is to be performed.  */
-
-static bool
-gate_copyrename (void)
-{
-  return flag_tree_copyrename != 0;
-}
-
 namespace {
 
 const pass_data pass_data_rename_ssa_copies =
@@ -468,7 +460,7 @@ public:
 
   /* opt_pass methods: */
   opt_pass * clone () { return new pass_rename_ssa_copies (m_ctxt); }
-  bool gate () { return gate_copyrename (); }
+  virtual bool gate (function *) { return flag_tree_copyrename != 0; }
   unsigned int execute () { return rename_ssa_copies (); }
 
 }; // class pass_rename_ssa_copies
diff --git a/gcc/tree-ssa-dce.c b/gcc/tree-ssa-dce.c
index 8db149e..e5799b9 100644
--- a/gcc/tree-ssa-dce.c
+++ b/gcc/tree-ssa-dce.c
@@ -1504,12 +1504,6 @@ tree_ssa_cd_dce (void)
   return perform_tree_ssa_dce (/*aggressive=*/optimize >= 2);
 }
 
-static bool
-gate_dce (void)
-{
-  return flag_tree_dce != 0;
-}
-
 namespace {
 
 const pass_data pass_data_dce =
@@ -1535,7 +1529,7 @@ public:
 
   /* opt_pass methods: */
   opt_pass * clone () { return new pass_dce (m_ctxt); }
-  bool gate () { return gate_dce (); }
+  virtual bool gate (function *) { return flag_tree_dce != 0; }
   unsigned int execute () { return tree_ssa_dce (); }
 
 }; // class pass_dce
@@ -1573,7 +1567,7 @@ public:
 
   /* opt_pass methods: */
   opt_pass * clone () { return new pass_dce_loop (m_ctxt); }
-  bool gate () { return gate_dce (); }
+  virtual bool gate (function *) { return flag_tree_dce != 0; }
   unsigned int execute () { return tree_ssa_dce_loop (); }
 
 }; // class pass_dce_loop
@@ -1611,7 +1605,7 @@ public:
 
   /* opt_pass methods: */
   opt_pass * clone () { return new pass_cd_dce (m_ctxt); }
-  bool gate () { return gate_dce (); }
+  virtual bool gate (function *) { return flag_tree_dce != 0; }
   unsigned int execute () { return tree_ssa_cd_dce (); }
 
 }; // class pass_cd_dce
diff --git a/gcc/tree-ssa-dom.c b/gcc/tree-ssa-dom.c
index 8101a54..b9cc5cc 100644
--- a/gcc/tree-ssa-dom.c
+++ b/gcc/tree-ssa-dom.c
@@ -952,12 +952,6 @@ tree_ssa_dominator_optimize (void)
   return 0;
 }
 
-static bool
-gate_dominator (void)
-{
-  return flag_tree_dom != 0;
-}
-
 namespace {
 
 const pass_data pass_data_dominator =
@@ -985,7 +979,7 @@ public:
 
   /* opt_pass methods: */
   opt_pass * clone () { return new pass_dominator (m_ctxt); }
-  bool gate () { return gate_dominator (); }
+  virtual bool gate (function *) { return flag_tree_dom != 0; }
   unsigned int execute () { return tree_ssa_dominator_optimize (); }
 
 }; // class pass_dominator
@@ -3142,7 +3136,7 @@ public:
 
   /* opt_pass methods: */
   opt_pass * clone () { return new pass_phi_only_cprop (m_ctxt); }
-  bool gate () { return gate_dominator (); }
+  virtual bool gate (function *) { return flag_tree_dom != 0; }
   unsigned int execute () { return eliminate_degenerate_phis (); }
 
 }; // class pass_phi_only_cprop
diff --git a/gcc/tree-ssa-dse.c b/gcc/tree-ssa-dse.c
index 0096b4c..b6fbdaf 100644
--- a/gcc/tree-ssa-dse.c
+++ b/gcc/tree-ssa-dse.c
@@ -80,7 +80,6 @@ along with GCC; see the file COPYING3.  If not see
    remove their dead edges eventually.  */
 static bitmap need_eh_cleanup;
 
-static bool gate_dse (void);
 static unsigned int tree_ssa_dse (void);
 
 
@@ -363,12 +362,6 @@ tree_ssa_dse (void)
   return 0;
 }
 
-static bool
-gate_dse (void)
-{
-  return flag_tree_dse != 0;
-}
-
 namespace {
 
 const pass_data pass_data_dse =
@@ -394,7 +387,7 @@ public:
 
   /* opt_pass methods: */
   opt_pass * clone () { return new pass_dse (m_ctxt); }
-  bool gate () { return gate_dse (); }
+  virtual bool gate (function *) { return flag_tree_dse != 0; }
   unsigned int execute () { return tree_ssa_dse (); }
 
 }; // class pass_dse
diff --git a/gcc/tree-ssa-forwprop.c b/gcc/tree-ssa-forwprop.c
index 66ae113..8d5ca5f 100644
--- a/gcc/tree-ssa-forwprop.c
+++ b/gcc/tree-ssa-forwprop.c
@@ -3831,13 +3831,6 @@ ssa_forward_propagate_and_combine (void)
   return todoflags;
 }
 
-
-static bool
-gate_forwprop (void)
-{
-  return flag_tree_forwprop;
-}
-
 namespace {
 
 const pass_data pass_data_forwprop =
@@ -3863,7 +3856,7 @@ public:
 
   /* opt_pass methods: */
   opt_pass * clone () { return new pass_forwprop (m_ctxt); }
-  bool gate () { return gate_forwprop (); }
+  virtual bool gate (function *) { return flag_tree_forwprop; }
   unsigned int execute () { return ssa_forward_propagate_and_combine (); }
 
 }; // class pass_forwprop
diff --git a/gcc/tree-ssa-ifcombine.c b/gcc/tree-ssa-ifcombine.c
index ef0c0c4..b901f37 100644
--- a/gcc/tree-ssa-ifcombine.c
+++ b/gcc/tree-ssa-ifcombine.c
@@ -756,12 +756,6 @@ tree_ssa_ifcombine (void)
   return cfg_changed ? TODO_cleanup_cfg : 0;
 }
 
-static bool
-gate_ifcombine (void)
-{
-  return 1;
-}
-
 namespace {
 
 const pass_data pass_data_tree_ifcombine =
@@ -786,7 +780,6 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_ifcombine (); }
   unsigned int execute () { return tree_ssa_ifcombine (); }
 
 }; // class pass_tree_ifcombine
diff --git a/gcc/tree-ssa-loop-ch.c b/gcc/tree-ssa-loop-ch.c
index 99cc39c..34d1f70 100644
--- a/gcc/tree-ssa-loop-ch.c
+++ b/gcc/tree-ssa-loop-ch.c
@@ -257,12 +257,6 @@ copy_loop_headers (void)
   return 0;
 }
 
-static bool
-gate_ch (void)
-{
-  return flag_tree_ch != 0;
-}
-
 namespace {
 
 const pass_data pass_data_ch =
@@ -288,7 +282,7 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_ch (); }
+  virtual bool gate (function *) { return flag_tree_ch != 0; }
   unsigned int execute () { return copy_loop_headers (); }
 
 }; // class pass_ch
diff --git a/gcc/tree-ssa-loop-im.c b/gcc/tree-ssa-loop-im.c
index aab521e..f38ee95 100644
--- a/gcc/tree-ssa-loop-im.c
+++ b/gcc/tree-ssa-loop-im.c
@@ -2538,12 +2538,6 @@ tree_ssa_loop_im (void)
   return tree_ssa_lim ();
 }
 
-static bool
-gate_tree_ssa_loop_im (void)
-{
-  return flag_tree_loop_im != 0;
-}
-
 namespace {
 
 const pass_data pass_data_lim =
@@ -2569,7 +2563,7 @@ public:
 
   /* opt_pass methods: */
   opt_pass * clone () { return new pass_lim (m_ctxt); }
-  bool gate () { return gate_tree_ssa_loop_im (); }
+  virtual bool gate (function *) { return flag_tree_loop_im != 0; }
   unsigned int execute () { return tree_ssa_loop_im (); }
 
 }; // class pass_lim
diff --git a/gcc/tree-ssa-loop-ivcanon.c b/gcc/tree-ssa-loop-ivcanon.c
index 177666d..df82816 100644
--- a/gcc/tree-ssa-loop-ivcanon.c
+++ b/gcc/tree-ssa-loop-ivcanon.c
@@ -1265,12 +1265,6 @@ tree_ssa_loop_ivcanon (void)
   return canonicalize_induction_variables ();
 }
 
-static bool
-gate_tree_ssa_loop_ivcanon (void)
-{
-  return flag_tree_loop_ivcanon != 0;
-}
-
 namespace {
 
 const pass_data pass_data_iv_canon =
@@ -1295,7 +1289,7 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_tree_ssa_loop_ivcanon (); }
+  virtual bool gate (function *) { return flag_tree_loop_ivcanon != 0; }
   unsigned int execute () { return tree_ssa_loop_ivcanon (); }
 
 }; // class pass_iv_canon
@@ -1321,12 +1315,6 @@ tree_complete_unroll (void)
 				       || optimize >= 3, true);
 }
 
-static bool
-gate_tree_complete_unroll (void)
-{
-  return true;
-}
-
 namespace {
 
 const pass_data pass_data_complete_unroll =
@@ -1351,7 +1339,6 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_tree_complete_unroll (); }
   unsigned int execute () { return tree_complete_unroll (); }
 
 }; // class pass_complete_unroll
@@ -1385,12 +1372,6 @@ tree_complete_unroll_inner (void)
   return ret;
 }
 
-static bool
-gate_tree_complete_unroll_inner (void)
-{
-  return optimize >= 2;
-}
-
 namespace {
 
 const pass_data pass_data_complete_unrolli =
@@ -1415,7 +1396,7 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_tree_complete_unroll_inner (); }
+  virtual bool gate (function *) { return optimize >= 2; }
   unsigned int execute () { return tree_complete_unroll_inner (); }
 
 }; // class pass_complete_unrolli
diff --git a/gcc/tree-ssa-loop-prefetch.c b/gcc/tree-ssa-loop-prefetch.c
index dd52703..17b13d1 100644
--- a/gcc/tree-ssa-loop-prefetch.c
+++ b/gcc/tree-ssa-loop-prefetch.c
@@ -2013,12 +2013,6 @@ tree_ssa_loop_prefetch (void)
   return tree_ssa_prefetch_arrays ();
 }
 
-static bool
-gate_tree_ssa_loop_prefetch (void)
-{
-  return flag_prefetch_loop_arrays > 0;
-}
-
 namespace {
 
 const pass_data pass_data_loop_prefetch =
@@ -2043,7 +2037,7 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_tree_ssa_loop_prefetch (); }
+  virtual bool gate (function *) { return flag_prefetch_loop_arrays > 0; }
   unsigned int execute () { return tree_ssa_loop_prefetch (); }
 
 }; // class pass_loop_prefetch
diff --git a/gcc/tree-ssa-loop-unswitch.c b/gcc/tree-ssa-loop-unswitch.c
index e755b62..90bb205 100644
--- a/gcc/tree-ssa-loop-unswitch.c
+++ b/gcc/tree-ssa-loop-unswitch.c
@@ -411,12 +411,6 @@ tree_ssa_loop_unswitch (void)
   return tree_ssa_unswitch_loops ();
 }
 
-static bool
-gate_tree_ssa_loop_unswitch (void)
-{
-  return flag_unswitch_loops != 0;
-}
-
 namespace {
 
 const pass_data pass_data_tree_unswitch =
@@ -441,7 +435,7 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_tree_ssa_loop_unswitch (); }
+  virtual bool gate (function *) { return flag_unswitch_loops != 0; }
   unsigned int execute () { return tree_ssa_loop_unswitch (); }
 
 }; // class pass_tree_unswitch
diff --git a/gcc/tree-ssa-loop.c b/gcc/tree-ssa-loop.c
index 84e24a1..38e7b13 100644
--- a/gcc/tree-ssa-loop.c
+++ b/gcc/tree-ssa-loop.c
@@ -44,12 +44,6 @@ along with GCC; see the file COPYING3.  If not see
 
 /* The loop superpass.  */
 
-static bool
-gate_tree_loop (void)
-{
-  return flag_tree_loop_optimize != 0;
-}
-
 namespace {
 
 const pass_data pass_data_tree_loop =
@@ -74,7 +68,7 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_tree_loop (); }
+  virtual bool gate (function *) { return flag_tree_loop_optimize != 0; }
 
 }; // class pass_tree_loop
 
@@ -152,12 +146,6 @@ tree_loop_vectorize (void)
   return vectorize_loops ();
 }
 
-static bool
-gate_tree_loop_vectorize (void)
-{
-  return flag_tree_loop_vectorize || cfun->has_force_vectorize_loops;
-}
-
 namespace {
 
 const pass_data pass_data_vectorize =
@@ -182,7 +170,11 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_tree_loop_vectorize (); }
+  virtual bool gate (function *fun)
+    {
+      return flag_tree_loop_vectorize || fun->has_force_vectorize_loops;
+    }
+
   unsigned int execute () { return tree_loop_vectorize (); }
 
 }; // class pass_vectorize
@@ -207,12 +199,6 @@ check_data_deps (void)
   return 0;
 }
 
-static bool
-gate_check_data_deps (void)
-{
-  return flag_check_data_deps != 0;
-}
-
 namespace {
 
 const pass_data pass_data_check_data_deps =
@@ -237,7 +223,7 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_check_data_deps (); }
+  virtual bool gate (function *) { return flag_check_data_deps != 0; }
   unsigned int execute () { return check_data_deps (); }
 
 }; // class pass_check_data_deps
@@ -252,12 +238,6 @@ make_pass_check_data_deps (gcc::context *ctxt)
 
 /* Propagation of constants using scev.  */
 
-static bool
-gate_scev_const_prop (void)
-{
-  return flag_tree_scev_cprop;
-}
-
 namespace {
 
 const pass_data pass_data_scev_cprop =
@@ -283,7 +263,7 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_scev_const_prop (); }
+  virtual bool gate (function *) { return flag_tree_scev_cprop; }
   unsigned int execute () { return scev_const_prop (); }
 
 }; // class pass_scev_cprop
@@ -357,12 +337,6 @@ tree_ssa_loop_ivopts (void)
   return 0;
 }
 
-static bool
-gate_tree_ssa_loop_ivopts (void)
-{
-  return flag_ivopts != 0;
-}
-
 namespace {
 
 const pass_data pass_data_iv_optimize =
@@ -387,7 +361,7 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_tree_ssa_loop_ivopts (); }
+  virtual bool gate (function *) { return flag_ivopts != 0; }
   unsigned int execute () { return tree_ssa_loop_ivopts (); }
 
 }; // class pass_iv_optimize
diff --git a/gcc/tree-ssa-math-opts.c b/gcc/tree-ssa-math-opts.c
index f63c75d..fef1b1e 100644
--- a/gcc/tree-ssa-math-opts.c
+++ b/gcc/tree-ssa-math-opts.c
@@ -504,12 +504,6 @@ execute_cse_reciprocals_1 (gimple_stmt_iterator *def_gsi, tree def)
   occ_head = NULL;
 }
 
-static bool
-gate_cse_reciprocals (void)
-{
-  return optimize && flag_reciprocal_math;
-}
-
 /* Go through all the floating-point SSA_NAMEs, and call
    execute_cse_reciprocals_1 on each of them.  */
 static unsigned int
@@ -678,7 +672,7 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_cse_reciprocals (); }
+  virtual bool gate (function *) { return optimize && flag_reciprocal_math; }
   unsigned int execute () { return execute_cse_reciprocals (); }
 
 }; // class pass_cse_reciprocals
@@ -1562,14 +1556,6 @@ execute_cse_sincos (void)
   return cfg_changed ? TODO_cleanup_cfg : 0;
 }
 
-static bool
-gate_cse_sincos (void)
-{
-  /* We no longer require either sincos or cexp, since powi expansion
-     piggybacks on this pass.  */
-  return optimize;
-}
-
 namespace {
 
 const pass_data pass_data_cse_sincos =
@@ -1595,7 +1581,13 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_cse_sincos (); }
+  virtual bool gate (function *)
+    {
+      /* We no longer require either sincos or cexp, since powi expansion
+	 piggybacks on this pass.  */
+      return optimize;
+    }
+
   unsigned int execute () { return execute_cse_sincos (); }
 
 }; // class pass_cse_sincos
@@ -2065,12 +2057,6 @@ execute_optimize_bswap (void)
 	  | TODO_verify_stmts : 0);
 }
 
-static bool
-gate_optimize_bswap (void)
-{
-  return flag_expensive_optimizations && optimize;
-}
-
 namespace {
 
 const pass_data pass_data_optimize_bswap =
@@ -2095,7 +2081,11 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_optimize_bswap (); }
+  virtual bool gate (function *)
+    {
+      return flag_expensive_optimizations && optimize;
+    }
+
   unsigned int execute () { return execute_optimize_bswap (); }
 
 }; // class pass_optimize_bswap
@@ -2874,12 +2864,6 @@ execute_optimize_widening_mul (void)
   return cfg_changed ? TODO_cleanup_cfg : 0;
 }
 
-static bool
-gate_optimize_widening_mul (void)
-{
-  return flag_expensive_optimizations && optimize;
-}
-
 namespace {
 
 const pass_data pass_data_optimize_widening_mul =
@@ -2905,7 +2889,11 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_optimize_widening_mul (); }
+  virtual bool gate (function *)
+    {
+      return flag_expensive_optimizations && optimize;
+    }
+
   unsigned int execute () { return execute_optimize_widening_mul (); }
 
 }; // class pass_optimize_widening_mul
diff --git a/gcc/tree-ssa-phiopt.c b/gcc/tree-ssa-phiopt.c
index 3892317..1ee39a5 100644
--- a/gcc/tree-ssa-phiopt.c
+++ b/gcc/tree-ssa-phiopt.c
@@ -2202,11 +2202,6 @@ gate_hoist_loads (void)
 
 /* Always do these optimizations if we have SSA
    trees to work on.  */
-static bool
-gate_phiopt (void)
-{
-  return 1;
-}
 
 namespace {
 
@@ -2234,7 +2229,6 @@ public:
 
   /* opt_pass methods: */
   opt_pass * clone () { return new pass_phiopt (m_ctxt); }
-  bool gate () { return gate_phiopt (); }
   unsigned int execute () { return tree_ssa_phiopt (); }
 
 }; // class pass_phiopt
@@ -2247,12 +2241,6 @@ make_pass_phiopt (gcc::context *ctxt)
   return new pass_phiopt (ctxt);
 }
 
-static bool
-gate_cselim (void)
-{
-  return flag_tree_cselim;
-}
-
 namespace {
 
 const pass_data pass_data_cselim =
@@ -2278,7 +2266,7 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_cselim (); }
+  virtual bool gate (function *) { return flag_tree_cselim; }
   unsigned int execute () { return tree_ssa_cs_elim (); }
 
 }; // class pass_cselim
diff --git a/gcc/tree-ssa-phiprop.c b/gcc/tree-ssa-phiprop.c
index d67f488..cbdbc6e 100644
--- a/gcc/tree-ssa-phiprop.c
+++ b/gcc/tree-ssa-phiprop.c
@@ -409,12 +409,6 @@ tree_ssa_phiprop (void)
   return 0;
 }
 
-static bool
-gate_phiprop (void)
-{
-  return flag_tree_phiprop;
-}
-
 namespace {
 
 const pass_data pass_data_phiprop =
@@ -439,7 +433,7 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_phiprop (); }
+  virtual bool gate (function *) { return flag_tree_phiprop; }
   unsigned int execute () { return tree_ssa_phiprop (); }
 
 }; // class pass_phiprop
diff --git a/gcc/tree-ssa-pre.c b/gcc/tree-ssa-pre.c
index 1329fe2..cda315a 100644
--- a/gcc/tree-ssa-pre.c
+++ b/gcc/tree-ssa-pre.c
@@ -4771,12 +4771,6 @@ do_pre (void)
   return todo;
 }
 
-static bool
-gate_pre (void)
-{
-  return flag_tree_pre != 0;
-}
-
 namespace {
 
 const pass_data pass_data_pre =
@@ -4803,7 +4797,7 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_pre (); }
+  virtual bool gate (function *) { return flag_tree_pre != 0; }
   unsigned int execute () { return do_pre (); }
 
 }; // class pass_pre
@@ -4842,12 +4836,6 @@ execute_fre (void)
   return todo;
 }
 
-static bool
-gate_fre (void)
-{
-  return flag_tree_fre != 0;
-}
-
 namespace {
 
 const pass_data pass_data_fre =
@@ -4873,7 +4861,7 @@ public:
 
   /* opt_pass methods: */
   opt_pass * clone () { return new pass_fre (m_ctxt); }
-  bool gate () { return gate_fre (); }
+  virtual bool gate (function *) { return flag_tree_fre != 0; }
   unsigned int execute () { return execute_fre (); }
 
 }; // class pass_fre
diff --git a/gcc/tree-ssa-reassoc.c b/gcc/tree-ssa-reassoc.c
index 0b37b7b..92a215a 100644
--- a/gcc/tree-ssa-reassoc.c
+++ b/gcc/tree-ssa-reassoc.c
@@ -4665,12 +4665,6 @@ execute_reassoc (void)
   return 0;
 }
 
-static bool
-gate_tree_ssa_reassoc (void)
-{
-  return flag_tree_reassoc != 0;
-}
-
 namespace {
 
 const pass_data pass_data_reassoc =
@@ -4698,7 +4692,7 @@ public:
 
   /* opt_pass methods: */
   opt_pass * clone () { return new pass_reassoc (m_ctxt); }
-  bool gate () { return gate_tree_ssa_reassoc (); }
+  virtual bool gate (function *) { return flag_tree_reassoc != 0; }
   unsigned int execute () { return execute_reassoc (); }
 
 }; // class pass_reassoc
diff --git a/gcc/tree-ssa-sink.c b/gcc/tree-ssa-sink.c
index 4a7410d..6803160 100644
--- a/gcc/tree-ssa-sink.c
+++ b/gcc/tree-ssa-sink.c
@@ -588,12 +588,6 @@ do_sink (void)
   return 0;
 }
 
-static bool
-gate_sink (void)
-{
-  return flag_tree_sink != 0;
-}
-
 namespace {
 
 const pass_data pass_data_sink_code =
@@ -621,7 +615,7 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_sink (); }
+  virtual bool gate (function *) { return flag_tree_sink != 0; }
   unsigned int execute () { return do_sink (); }
 
 }; // class pass_sink_code
diff --git a/gcc/tree-ssa-strlen.c b/gcc/tree-ssa-strlen.c
index aa6b6b9..fb83093 100644
--- a/gcc/tree-ssa-strlen.c
+++ b/gcc/tree-ssa-strlen.c
@@ -2089,12 +2089,6 @@ tree_ssa_strlen (void)
   return 0;
 }
 
-static bool
-gate_strlen (void)
-{
-  return flag_optimize_strlen != 0;
-}
-
 namespace {
 
 const pass_data pass_data_strlen =
@@ -2119,7 +2113,7 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_strlen (); }
+  virtual bool gate (function *) { return flag_optimize_strlen != 0; }
   unsigned int execute () { return tree_ssa_strlen (); }
 
 }; // class pass_strlen
diff --git a/gcc/tree-ssa-structalias.c b/gcc/tree-ssa-structalias.c
index 9e1cdbc..3548ac5 100644
--- a/gcc/tree-ssa-structalias.c
+++ b/gcc/tree-ssa-structalias.c
@@ -6989,12 +6989,6 @@ compute_may_aliases (void)
   return 0;
 }
 
-static bool
-gate_tree_pta (void)
-{
-  return flag_tree_pta;
-}
-
 /* A dummy pass to cause points-to information to be computed via
    TODO_rebuild_alias.  */
 
@@ -7022,7 +7016,7 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_tree_pta (); }
+  virtual bool gate (function *) { return flag_tree_pta; }
 
 }; // class pass_build_alias
 
@@ -7061,7 +7055,7 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_tree_pta (); }
+  virtual bool gate (function *) { return flag_tree_pta; }
 
 }; // class pass_build_ealias
 
@@ -7074,16 +7068,6 @@ make_pass_build_ealias (gcc::context *ctxt)
 }
 
 
-/* Return true if we should execute IPA PTA.  */
-static bool
-gate_ipa_pta (void)
-{
-  return (optimize
-	  && flag_ipa_pta
-	  /* Don't bother doing anything if the program has errors.  */
-	  && !seen_error ());
-}
-
 /* IPA PTA solutions for ESCAPED.  */
 struct pt_solution ipa_escaped_pt
   = { true, false, false, false, false, false, false, false, NULL };
@@ -7452,7 +7436,14 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_ipa_pta (); }
+  virtual bool gate (function *)
+    {
+      return (optimize
+	      && flag_ipa_pta
+	      /* Don't bother doing anything if the program has errors.  */
+	      && !seen_error ());
+    }
+
   unsigned int execute () { return ipa_pta_execute (); }
 
 }; // class pass_ipa_pta
diff --git a/gcc/tree-ssa-uncprop.c b/gcc/tree-ssa-uncprop.c
index 41f4bd8..e39ce88 100644
--- a/gcc/tree-ssa-uncprop.c
+++ b/gcc/tree-ssa-uncprop.c
@@ -581,12 +581,6 @@ uncprop_dom_walker::before_dom_children (basic_block bb)
   uncprop_into_successor_phis (bb);
 }
 
-static bool
-gate_uncprop (void)
-{
-  return flag_tree_dom != 0;
-}
-
 namespace {
 
 const pass_data pass_data_uncprop =
@@ -612,7 +606,7 @@ public:
 
   /* opt_pass methods: */
   opt_pass * clone () { return new pass_uncprop (m_ctxt); }
-  bool gate () { return gate_uncprop (); }
+  virtual bool gate (function *) { return flag_tree_dom != 0; }
   unsigned int execute () { return tree_ssa_uncprop (); }
 
 }; // class pass_uncprop
diff --git a/gcc/tree-ssa-uninit.c b/gcc/tree-ssa-uninit.c
index 86d84a1..03ff3b8 100644
--- a/gcc/tree-ssa-uninit.c
+++ b/gcc/tree-ssa-uninit.c
@@ -2383,7 +2383,7 @@ public:
 
   /* opt_pass methods: */
   opt_pass * clone () { return new pass_late_warn_uninitialized (m_ctxt); }
-  bool gate () { return gate_warn_uninitialized (); }
+  virtual bool gate (function *) { return gate_warn_uninitialized (); }
   unsigned int execute () { return execute_late_warn_uninitialized (); }
 
 }; // class pass_late_warn_uninitialized
@@ -2441,7 +2441,7 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_warn_uninitialized (); }
+  virtual bool gate (function *) { return gate_warn_uninitialized (); }
   unsigned int execute () { return execute_early_warn_uninitialized (); }
 
 }; // class pass_early_warn_uninitialized
diff --git a/gcc/tree-ssa.c b/gcc/tree-ssa.c
index ecc8da3..52126ca 100644
--- a/gcc/tree-ssa.c
+++ b/gcc/tree-ssa.c
@@ -1139,15 +1139,6 @@ execute_init_datastructures (void)
   return 0;
 }
 
-/* Gate for IPCP optimization.  */
-
-static bool
-gate_init_datastructures (void)
-{
-  /* Do nothing for funcions that was produced already in SSA form.  */
-  return !(cfun->curr_properties & PROP_ssa);
-}
-
 namespace {
 
 const pass_data pass_data_init_datastructures =
@@ -1172,7 +1163,12 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_init_datastructures (); }
+  virtual bool gate (function *fun)
+    {
+      /* Do nothing for funcions that was produced already in SSA form.  */
+      return !(fun->curr_properties & PROP_ssa);
+    }
+
   unsigned int execute () { return execute_init_datastructures (); }
 
 }; // class pass_init_datastructures
diff --git a/gcc/tree-stdarg.c b/gcc/tree-stdarg.c
index 7da36c4..710711b 100644
--- a/gcc/tree-stdarg.c
+++ b/gcc/tree-stdarg.c
@@ -663,18 +663,6 @@ check_all_va_list_escapes (struct stdarg_info *si)
   return false;
 }
 
-
-/* Return true if this optimization pass should be done.
-   It makes only sense for stdarg functions.  */
-
-static bool
-gate_optimize_stdarg (void)
-{
-  /* This optimization is only for stdarg functions.  */
-  return cfun->stdarg != 0;
-}
-
-
 /* Entry point to the stdarg optimization pass.  */
 
 static unsigned int
@@ -1023,7 +1011,12 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_optimize_stdarg (); }
+  virtual bool gate (function *fun)
+    {
+      /* This optimization is only for stdarg functions.  */
+      return fun->stdarg != 0;
+    }
+
   unsigned int execute () { return execute_optimize_stdarg (); }
 
 }; // class pass_stdarg
diff --git a/gcc/tree-switch-conversion.c b/gcc/tree-switch-conversion.c
index cf2e763..a0f9d19 100644
--- a/gcc/tree-switch-conversion.c
+++ b/gcc/tree-switch-conversion.c
@@ -1465,14 +1465,6 @@ do_switchconv (void)
   return 0;
 }
 
-/* The pass gate. */
-
-static bool
-switchconv_gate (void)
-{
-  return flag_tree_switch_conversion != 0;
-}
-
 namespace {
 
 const pass_data pass_data_convert_switch =
@@ -1499,7 +1491,7 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return switchconv_gate (); }
+  virtual bool gate (function *) { return flag_tree_switch_conversion != 0; }
   unsigned int execute () { return do_switchconv (); }
 
 }; // class pass_convert_switch
diff --git a/gcc/tree-tailcall.c b/gcc/tree-tailcall.c
index b3a6256..84cdbde 100644
--- a/gcc/tree-tailcall.c
+++ b/gcc/tree-tailcall.c
@@ -1108,7 +1108,7 @@ public:
 
   /* opt_pass methods: */
   opt_pass * clone () { return new pass_tail_recursion (m_ctxt); }
-  bool gate () { return gate_tail_calls (); }
+  virtual bool gate (function *) { return gate_tail_calls (); }
   unsigned int execute () { return execute_tail_recursion (); }
 
 }; // class pass_tail_recursion
@@ -1145,7 +1145,7 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_tail_calls (); }
+  virtual bool gate (function *) { return gate_tail_calls (); }
   unsigned int execute () { return execute_tail_calls (); }
 
 }; // class pass_tail_calls
diff --git a/gcc/tree-vect-generic.c b/gcc/tree-vect-generic.c
index 035c143..4274417 100644
--- a/gcc/tree-vect-generic.c
+++ b/gcc/tree-vect-generic.c
@@ -1528,12 +1528,6 @@ expand_vector_operations_1 (gimple_stmt_iterator *gsi)
 /* Use this to lower vector operations introduced by the vectorizer,
    if it may need the bit-twiddling tricks implemented in this file.  */
 
-static bool
-gate_expand_vector_operations_ssa (void)
-{
-  return !(cfun->curr_properties & PROP_gimple_lvec);
-}
-
 static unsigned int
 expand_vector_operations (void)
 {
@@ -1586,7 +1580,11 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_expand_vector_operations_ssa (); }
+  virtual bool gate (function *fun)
+    {
+      return !(fun->curr_properties & PROP_gimple_lvec);
+    }
+
   unsigned int execute () { return expand_vector_operations (); }
 
 }; // class pass_lower_vector
diff --git a/gcc/tree-vectorizer.c b/gcc/tree-vectorizer.c
index 17be3aa..7b5691a 100644
--- a/gcc/tree-vectorizer.c
+++ b/gcc/tree-vectorizer.c
@@ -613,12 +613,6 @@ execute_vect_slp (void)
   return 0;
 }
 
-static bool
-gate_vect_slp (void)
-{
-  return flag_tree_slp_vectorize != 0;
-}
-
 namespace {
 
 const pass_data pass_data_slp_vectorize =
@@ -644,7 +638,7 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_vect_slp (); }
+  virtual bool gate (function *) { return flag_tree_slp_vectorize != 0; }
   unsigned int execute () { return execute_vect_slp (); }
 
 }; // class pass_slp_vectorize
@@ -702,13 +696,6 @@ increase_alignment (void)
 }
 
 
-static bool
-gate_increase_alignment (void)
-{
-  return flag_section_anchors && flag_tree_loop_vectorize;
-}
-
-
 namespace {
 
 const pass_data pass_data_ipa_increase_alignment =
@@ -733,7 +720,11 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_increase_alignment (); }
+  virtual bool gate (function *)
+    {
+      return flag_section_anchors && flag_tree_loop_vectorize;
+    }
+
   unsigned int execute () { return increase_alignment (); }
 
 }; // class pass_ipa_increase_alignment
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
index 4ccb90b..80f3888 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -9894,12 +9894,6 @@ execute_vrp (void)
   return 0;
 }
 
-static bool
-gate_vrp (void)
-{
-  return flag_tree_vrp != 0;
-}
-
 namespace {
 
 const pass_data pass_data_vrp =
@@ -9927,7 +9921,7 @@ public:
 
   /* opt_pass methods: */
   opt_pass * clone () { return new pass_vrp (m_ctxt); }
-  bool gate () { return gate_vrp (); }
+  virtual bool gate (function *) { return flag_tree_vrp != 0; }
   unsigned int execute () { return execute_vrp (); }
 
 }; // class pass_vrp
diff --git a/gcc/tsan.c b/gcc/tsan.c
index f30cf57..b413bb5 100644
--- a/gcc/tsan.c
+++ b/gcc/tsan.c
@@ -715,14 +715,6 @@ tsan_pass (void)
   return 0;
 }
 
-/* The pass's gate.  */
-
-static bool
-tsan_gate (void)
-{
-  return (flag_sanitize & SANITIZE_THREAD) != 0;
-}
-
 /* Inserts __tsan_init () into the list of CTORs.  */
 
 void
@@ -765,7 +757,11 @@ public:
 
   /* opt_pass methods: */
   opt_pass * clone () { return new pass_tsan (m_ctxt); }
-  bool gate () { return tsan_gate (); }
+  virtual bool gate (function *)
+{
+  return (flag_sanitize & SANITIZE_THREAD) != 0;
+}
+
   unsigned int execute () { return tsan_pass (); }
 
 }; // class pass_tsan
@@ -778,12 +774,6 @@ make_pass_tsan (gcc::context *ctxt)
   return new pass_tsan (ctxt);
 }
 
-static bool
-tsan_gate_O0 (void)
-{
-  return (flag_sanitize & SANITIZE_THREAD) != 0 && !optimize;
-}
-
 namespace {
 
 const pass_data pass_data_tsan_O0 =
@@ -808,7 +798,11 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return tsan_gate_O0 (); }
+  virtual bool gate (function *)
+    {
+      return (flag_sanitize & SANITIZE_THREAD) != 0 && !optimize;
+    }
+
   unsigned int execute () { return tsan_pass (); }
 
 }; // class pass_tsan_O0
diff --git a/gcc/ubsan.c b/gcc/ubsan.c
index c205e6b..8e7dda5 100644
--- a/gcc/ubsan.c
+++ b/gcc/ubsan.c
@@ -902,13 +902,6 @@ ubsan_pass (void)
   return 0;
 }
 
-static bool
-gate_ubsan (void)
-{
-  return flag_sanitize & (SANITIZE_NULL | SANITIZE_SI_OVERFLOW
-			  | SANITIZE_BOOL | SANITIZE_ENUM);
-}
-
 namespace {
 
 const pass_data pass_data_ubsan =
@@ -933,7 +926,12 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_ubsan (); }
+  virtual bool gate (function *)
+    {
+      return flag_sanitize & (SANITIZE_NULL | SANITIZE_SI_OVERFLOW
+			      | SANITIZE_BOOL | SANITIZE_ENUM);
+    }
+
   unsigned int execute () { return ubsan_pass (); }
 
 }; // class pass_ubsan
diff --git a/gcc/var-tracking.c b/gcc/var-tracking.c
index e6ca3af..4586afc 100644
--- a/gcc/var-tracking.c
+++ b/gcc/var-tracking.c
@@ -10344,14 +10344,6 @@ variable_tracking_main (void)
   return ret;
 }
 
-static bool
-gate_handle_var_tracking (void)
-{
-  return (flag_var_tracking && !targetm.delay_vartrack);
-}
-
-
-
 namespace {
 
 const pass_data pass_data_variable_tracking =
@@ -10376,7 +10368,11 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_handle_var_tracking (); }
+  virtual bool gate (function *)
+    {
+      return (flag_var_tracking && !targetm.delay_vartrack);
+    }
+
   unsigned int execute () { return variable_tracking_main (); }
 
 }; // class pass_variable_tracking
diff --git a/gcc/vtable-verify.c b/gcc/vtable-verify.c
index 99caa88..601b2ce 100644
--- a/gcc/vtable-verify.c
+++ b/gcc/vtable-verify.c
@@ -740,14 +740,6 @@ vtable_verify_main (void)
   return ret;
 }
 
-/* Gate function for the pass.  */
-
-static bool
-gate_tree_vtable_verify (void)
-{
-  return (flag_vtable_verify);
-}
-
 /* Definition of this optimization pass.  */
 
 namespace {
@@ -774,7 +766,7 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_tree_vtable_verify (); }
+  virtual bool gate (function *) { return (flag_vtable_verify); }
   unsigned int execute () { return vtable_verify_main (); }
 
 }; // class pass_vtable_verify
diff --git a/gcc/web.c b/gcc/web.c
index ba4172e..50fc9e6 100644
--- a/gcc/web.c
+++ b/gcc/web.c
@@ -325,12 +325,6 @@ replace_ref (df_ref ref, rtx reg)
 }
 
 
-static bool
-gate_handle_web (void)
-{
-  return (optimize > 0 && flag_web);
-}
-
 /* Main entry point.  */
 
 static unsigned int
@@ -473,7 +467,7 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_handle_web (); }
+  virtual bool gate (function *) { return (optimize > 0 && flag_web); }
   unsigned int execute () { return web_main (); }
 
 }; // class pass_web
-- 
1.9.2



More information about the Gcc-patches mailing list